mirror of
https://github.com/ganelson/inform.git
synced 2024-07-16 22:14:23 +03:00
424 lines
36 KiB
HTML
424 lines
36 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
<html>
|
|
<head>
|
|
<title>Inform Primitives</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="../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 'Inform Primitives' 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>Inform Primitives</b></li></ul></div>
|
|
<p class="purpose">The standard set of primitive invocations used within Inform.</p>
|
|
|
|
<ul class="toc"><li><a href="M-ip.html#SP1">§1. What standard means</a></li><li><a href="M-ip.html#SP2">§2. Arithmetic</a></li><li><a href="M-ip.html#SP3">§3. Logical operators</a></li><li><a href="M-ip.html#SP4">§4. Bitwise operators</a></li><li><a href="M-ip.html#SP5">§5. Numerical comparison</a></li><li><a href="M-ip.html#SP6">§6. Sequential evaluation</a></li><li><a href="M-ip.html#SP7">§7. Random</a></li><li><a href="M-ip.html#SP8">§8. Printing</a></li><li><a href="M-ip.html#SP9">§9. Stack access</a></li><li><a href="M-ip.html#SP10">§10. Accessing storage</a></li><li><a href="M-ip.html#SP11">§11. Indirect function calls</a></li><li><a href="M-ip.html#SP12">§12. Message function calls</a></li><li><a href="M-ip.html#SP13">§13. External function calls</a></li><li><a href="M-ip.html#SP14">§14. Control flow</a></li><li><a href="M-ip.html#SP15">§15. Interactive fiction-only primitives</a></li></ul><hr class="tocbar">
|
|
|
|
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>§1. What standard means. </b>To recap from <a href="M-cpiti.html" class="internal">Code Packages in Textual Inter</a>, primitives are like built-in
|
|
atomic operations. The Inter specification allows for any desired set of
|
|
primitives to be used, provided they are declared. However, in practice
|
|
the <a href="../building-module/index.html" class="internal">building</a> module of Inter defines a standard set of 95 or so primitives
|
|
which are used across the Inform tool-chain, and:
|
|
</p>
|
|
|
|
<ul class="items"><li>● The front end of the Inform compiler invokes only (a subset of) this
|
|
standard set of primitives.
|
|
</li><li>● The back end guarantees to be able to perform final code-generation to
|
|
any supported platform on the whole of this standard set.
|
|
</li></ul>
|
|
<p class="commentary">That means the standard set is (for now at least) the only game in town, and
|
|
the following catalogue runs through it. Textual Inter code does not need
|
|
to declare primitives if they belong to this standard set, but the
|
|
declarations they have behind the scenes are all listed below.
|
|
</p>
|
|
|
|
<p class="commentary">(See <a href="../building-module/1-ip.html" class="internal">Inter Primitives (in building)</a> for where in the <a href="index.html" class="internal">inter</a> source code
|
|
these primitives are defined.)
|
|
</p>
|
|
|
|
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>§2. Arithmetic. </b>The following are standard integer arithmetic operations, using signed
|
|
twos-complement integers:
|
|
</p>
|
|
|
|
<ul class="items"><li>(a) <span class="extract"><span class="extract-syntax">primitive !plus val val -> val</span></span>. 16 or 32-bit integer addition.
|
|
</li><li>(b) <span class="extract"><span class="extract-syntax">primitive !minus val val -> val</span></span>. 16 or 32-bit integer subtraction.
|
|
</li><li>(c) <span class="extract"><span class="extract-syntax">primitive !unaryminus val -> val</span></span>. Equivalent to performing <span class="extract"><span class="extract-syntax">0 - x</span></span>.
|
|
</li><li>(d) <span class="extract"><span class="extract-syntax">primitive !times val val -> val</span></span>. 16 or 32-bit integer multiplication.
|
|
</li><li>(e) <span class="extract"><span class="extract-syntax">primitive !divide val val -> val</span></span>. 16 or 32-bit integer division.
|
|
</li><li>(f) <span class="extract"><span class="extract-syntax">primitive !modulo val val -> val</span></span>. Remainder after such a division.
|
|
</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>§3. Logical operators. </b>In general, the value 0 is false, and all other values are true.
|
|
</p>
|
|
|
|
<ul class="items"><li>(a) <span class="extract"><span class="extract-syntax">primitive !not val -> val</span></span>. True if the value is false, and vice versa.
|
|
</li><li>(b) <span class="extract"><span class="extract-syntax">primitive !and val val -> val</span></span>. True if both are true: doesn't evaluate the
|
|
second if the first is false.
|
|
</li><li>(c) <span class="extract"><span class="extract-syntax">primitive !or val val -> val</span></span>. True if either is true: doesn't evaluate the
|
|
second if the first is true.
|
|
</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>§4. Bitwise operators. </b>These differ in that they do not "short circuit", and do not squash values
|
|
down to just 0 or 1.
|
|
</p>
|
|
|
|
<ul class="items"><li>(a) <span class="extract"><span class="extract-syntax">primitive !bitwiseand val val -> val</span></span>.
|
|
</li><li>(a) <span class="extract"><span class="extract-syntax">primitive !bitwiseor val val -> val</span></span>.
|
|
</li><li>(a) <span class="extract"><span class="extract-syntax">primitive !bitwisenot val -> val</span></span>.
|
|
</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>§5. Numerical comparison. </b>These are comparisons of signed integers. (If Inform needs to compare unsigned
|
|
integers, it calls a routine in the I6 template.)
|
|
</p>
|
|
|
|
<ul class="items"><li>(a) <span class="extract"><span class="extract-syntax">primitive !eq val val -> val</span></span>.
|
|
</li><li>(b) <span class="extract"><span class="extract-syntax">primitive !ne val val -> val</span></span>.
|
|
</li><li>(c) <span class="extract"><span class="extract-syntax">primitive !gt val val -> val</span></span>.
|
|
</li><li>(d) <span class="extract"><span class="extract-syntax">primitive !ge val val -> val</span></span>.
|
|
</li><li>(e) <span class="extract"><span class="extract-syntax">primitive !lt val val -> val</span></span>.
|
|
</li><li>(f) <span class="extract"><span class="extract-syntax">primitive !le val val -> val</span></span>.
|
|
</li></ul>
|
|
<p class="commentary">This is a special operation allowing the comparisons to test for multiple
|
|
possibilities at once. (Old-school Inform 6 users will recognise it as the
|
|
<span class="extract"><span class="extract-syntax">or</span></span> operator.)
|
|
</p>
|
|
|
|
<ul class="items"><li>(a) <span class="extract"><span class="extract-syntax">!alternative val val -> val</span></span>
|
|
</li></ul>
|
|
<p class="commentary">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">!eq</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">inv</span><span class="plain-syntax"> </span><span class="function-syntax">!alternative</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">val</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="constant-syntax">7</span>
|
|
</pre>
|
|
<p class="commentary">tests whether <span class="extract"><span class="extract-syntax">x</span></span> equals either 2 or 7.
|
|
</p>
|
|
|
|
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></a><b>§6. Sequential evaluation. </b>The reason for the existence of <span class="extract"><span class="extract-syntax">!ternarysequential</span></span> is that it's a convenient
|
|
shorthand, and also that it helps the code generator with I6 generation,
|
|
because I6 has problems with the syntax of complicated sequential evals.
|
|
</p>
|
|
|
|
<ul class="items"><li>(a) <span class="extract"><span class="extract-syntax">primitive !sequential val val -> val</span></span>. Evaluates the first, then the second
|
|
value, producing that second value.
|
|
</li><li>(a) <span class="extract"><span class="extract-syntax">primitive !ternarysequential val val val -> val</span></span>. Evaluates the first,
|
|
then the second, then the third value, producing that third value.
|
|
</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>§7. Random. </b>This is essentially the built-in <span class="extract"><span class="extract-syntax">random</span></span> function of Inform 6, given an Inter
|
|
disguise. See the Inform 6 Designer's Manual for a specification.
|
|
</p>
|
|
|
|
<ul class="items"><li>(a) <span class="extract"><span class="extract-syntax">!primitive random val -> val</span></span>.
|
|
</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP8" class="paragraph-anchor"></a><b>§8. Printing. </b>These print data of various kinds:
|
|
</p>
|
|
|
|
<ul class="items"><li>(a) <span class="extract"><span class="extract-syntax">primitive !print val -> void</span></span>. Print text.
|
|
</li><li>(b) <span class="extract"><span class="extract-syntax">primitive !printnumber val -> void</span></span>. Print a (signed) number in decimal.
|
|
</li><li>(c) <span class="extract"><span class="extract-syntax">primitive !printchar val -> void</span></span>. Print a character value.
|
|
</li><li>(d) <span class="extract"><span class="extract-syntax">primitive !printnl void -> void</span></span>. Print a newline. (This is needed because
|
|
some of our VMs use character 10 for newline, and crash on 13, and others vice versa.)
|
|
</li><li>(e) <span class="extract"><span class="extract-syntax">primitive !printdword val -> void</span></span>. Print a dictionary word.
|
|
</li><li>(f) <span class="extract"><span class="extract-syntax">primitive !printstring val -> void</span></span>. Print a packed string.
|
|
</li></ul>
|
|
<p class="commentary">There are also two primitive ways to change the visual style of text:
|
|
</p>
|
|
|
|
<ul class="items"><li>(a) <span class="extract"><span class="extract-syntax">primitive !font val -> void</span></span>. Change to fixed-width font if value is 1, or regular if 0.
|
|
</li><li>(b) <span class="extract"><span class="extract-syntax">primitive !style val -> void</span></span>. Change to this text style.
|
|
</li></ul>
|
|
<p class="commentary">The effect of these will depend on the platform the final Inter code is generated
|
|
for. If the value supplied to <span class="extract"><span class="extract-syntax">!style</span></span> is 0, 1, 2 or 3, then this should make an
|
|
effort to achieve roman, bold, italic, or reverse-video type, respectively, and
|
|
that should apply across all platforms. Use of any other value is likely to be
|
|
less portable. On C, for example, all other uses of <span class="extract"><span class="extract-syntax">!style</span></span> are (Inform) text
|
|
values which supply names for styles.
|
|
</p>
|
|
|
|
<p class="commentary">Then there is a primitive for a rum feature of Inform 6 allowing for the display of
|
|
"box quotations" on screen:
|
|
</p>
|
|
|
|
<ul class="items"><li>(a) <span class="extract"><span class="extract-syntax">primitive !box val -> void</span></span>.
|
|
</li></ul>
|
|
<p class="commentary">And another largely pointless primitive for issuing a run of a certain number of
|
|
spaces, for users too lazy to write their own loops:
|
|
</p>
|
|
|
|
<ul class="items"><li>(a) <span class="extract"><span class="extract-syntax">primitive !spaces val -> void</span></span>.
|
|
</li></ul>
|
|
<p class="commentary">On some platforms, active steps need to be taken before text can actually appear:
|
|
for example, those using the Glk input/output framework. As a convenience, this
|
|
primitive will do anything which might be necessary. <a href="../inform7/index.html" class="internal">inform7</a> doesn't use
|
|
this, instead compiling its own code to activate Glk, but it's useful to have
|
|
this opcode for making small Inter test cases work:
|
|
</p>
|
|
|
|
<ul class="items"><li>(a) !primitive !enableprinting void -> void<span class="extract"><span class="extract-syntax">.
|
|
</span></span></li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP9" class="paragraph-anchor"></a><b>§9. Stack access. </b>The stack is not directly accessible anywhere in memory, so the only access
|
|
is via the following.
|
|
</p>
|
|
|
|
<ul class="items"><li>(a) <span class="extract"><span class="extract-syntax">primitive !push val -> void</span></span>. Push value onto the stack.
|
|
</li><li>(b) <span class="extract"><span class="extract-syntax">primitive !pull ref -> void</span></span>. Pull value from the stack and write it into
|
|
the storage referred to. Values on the stack have unchecked kinds: it's up to
|
|
the author not to pull an inappropriate value.
|
|
</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP10" class="paragraph-anchor"></a><b>§10. Accessing storage. </b>Here the <span class="extract"><span class="extract-syntax">ref</span></span> term is a reference to a piece of storage: a property of an
|
|
instance, or a global variable, or an entry in memory, for example.
|
|
</p>
|
|
|
|
<ul class="items"><li>(a) <span class="extract"><span class="extract-syntax">primitive !store ref val -> val</span></span>. Put the value in <span class="extract"><span class="extract-syntax">ref</span></span>.
|
|
</li><li>(b) <span class="extract"><span class="extract-syntax">primitive !setbit ref val -> void</span></span>. Set bits in the mask <span class="extract"><span class="extract-syntax">val</span></span> in <span class="extract"><span class="extract-syntax">ref</span></span>.
|
|
</li><li>(c) <span class="extract"><span class="extract-syntax">primitive !clearbit ref val -> void</span></span>. Clear bits in the mask <span class="extract"><span class="extract-syntax">val</span></span> in <span class="extract"><span class="extract-syntax">ref</span></span>.
|
|
</li><li>(d) <span class="extract"><span class="extract-syntax">primitive !postincrement ref -> val</span></span>. Performs the equivalent of <span class="extract"><span class="extract-syntax">ref++</span></span>.
|
|
</li><li>(e) <span class="extract"><span class="extract-syntax">primitive !preincrement ref -> val</span></span>. Performs the equivalent of <span class="extract"><span class="extract-syntax">++ref</span></span>.
|
|
</li><li>(f) <span class="extract"><span class="extract-syntax">primitive !postdecrement ref -> val</span></span>. Performs the equivalent of <span class="extract"><span class="extract-syntax">ref--</span></span>.
|
|
</li><li>(g) <span class="extract"><span class="extract-syntax">primitive !predecrement ref -> val</span></span>. Performs the equivalent of <span class="extract"><span class="extract-syntax">--ref</span></span>.
|
|
</li></ul>
|
|
<p class="commentary">Memory can be accessed with the following. The first value is the address of
|
|
the array; the second is an offset, that is, with 0 being the first entry,
|
|
1 the second, and so on. "Word" in this context means either an <span class="extract"><span class="extract-syntax">int16</span></span> or
|
|
an <span class="extract"><span class="extract-syntax">int32</span></span>, depending on what virtual machine are compiling to.
|
|
</p>
|
|
|
|
<ul class="items"><li>(a) <span class="extract"><span class="extract-syntax">primitive !lookup val val -> val</span></span>. Find word at this word offset.
|
|
</li><li>(b) <span class="extract"><span class="extract-syntax">primitive !lookupbyte val val -> val</span></span>. Find byte at this byte offset.
|
|
</li></ul>
|
|
<p class="commentary">Properties, like memory, can be converted to <span class="extract"><span class="extract-syntax">ref</span></span> in order to write to them,
|
|
and are accessible with <span class="extract"><span class="extract-syntax">propertyvalue</span></span>. Their existence can be tested with
|
|
<span class="extract"><span class="extract-syntax">propertyexists</span></span>; the other two opcodes here are for the handful of "inline
|
|
property values", where a property stores not a single value but a small array.
|
|
In each of the four ternary property primitives, the operands are <span class="extract"><span class="extract-syntax">K</span></span>, the
|
|
weak kind ID of the owner; <span class="extract"><span class="extract-syntax">O</span></span>, the owner; and <span class="extract"><span class="extract-syntax">P</span></span>, the property. For properties
|
|
of objects, <span class="extract"><span class="extract-syntax">K</span></span> will always be <span class="extract"><span class="extract-syntax">OBJECT_TY</span></span>.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="extract"><span class="extract-syntax">propertyarray</span></span> and <span class="extract"><span class="extract-syntax">propertylength</span></span> both produce 0 (but not a run-time error)
|
|
if called on a property value which does not exist, or is not an inline array.
|
|
In particular, they always produce 0 if the owner <span class="extract"><span class="extract-syntax">O</span></span> is not an object, since
|
|
only objects can have inline property values.
|
|
</p>
|
|
|
|
<ul class="items"><li>(a) <span class="extract"><span class="extract-syntax">primitive !propertyvalue val val val -> val</span></span>.
|
|
</li><li>(b) <span class="extract"><span class="extract-syntax">primitive !propertyarray val val val -> val</span></span>.
|
|
</li><li>(c) <span class="extract"><span class="extract-syntax">primitive !propertylength val val val -> val</span></span>.
|
|
</li><li>(d) <span class="extract"><span class="extract-syntax">primitive !propertyexists val val val -> val</span></span>.
|
|
</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP11" class="paragraph-anchor"></a><b>§11. Indirect function calls. </b>Invocations of functions can only be made with <span class="extract"><span class="extract-syntax">inv</span></span> when the function is
|
|
specified as a constant, and when its signature is therefore known. If
|
|
we need to call "whatever function this variable refers to", we have to
|
|
use one of the following. They differ only in their signatures. The
|
|
first value is the function address, and subsequent ones are arguments.
|
|
</p>
|
|
|
|
<ul class="items"><li>(a) <span class="extract"><span class="extract-syntax">primitive !indirect0v val -> void</span></span>.
|
|
</li><li>(b) <span class="extract"><span class="extract-syntax">primitive !indirect1v val val -> void</span></span>.
|
|
</li><li>(c) <span class="extract"><span class="extract-syntax">primitive !indirect2v val val val -> void</span></span>.
|
|
</li><li>(d) <span class="extract"><span class="extract-syntax">primitive !indirect3v val val val val -> void</span></span>.
|
|
</li><li>(e) <span class="extract"><span class="extract-syntax">primitive !indirect4v val val val val val -> void</span></span>.
|
|
</li><li>(f) <span class="extract"><span class="extract-syntax">primitive !indirect5v val val val val val val -> void</span></span>.
|
|
</li><li>(g) <span class="extract"><span class="extract-syntax">primitive !indirect0 val -> val</span></span>.
|
|
</li><li>(h) <span class="extract"><span class="extract-syntax">primitive !indirect1 val val -> val</span></span>.
|
|
</li><li>(i) <span class="extract"><span class="extract-syntax">primitive !indirect2 val val val -> val</span></span>.
|
|
</li><li>(j) <span class="extract"><span class="extract-syntax">primitive !indirect3 val val val val -> val</span></span>.
|
|
</li><li>(k) <span class="extract"><span class="extract-syntax">primitive !indirect4 val val val val val -> val</span></span>.
|
|
</li><li>(l) <span class="extract"><span class="extract-syntax">primitive !indirect5 val val val val val val -> val</span></span>.
|
|
</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP12" class="paragraph-anchor"></a><b>§12. Message function calls. </b>These are the special form of function call from Inform 6 with the syntax
|
|
<span class="extract"><span class="extract-syntax">a.b()</span></span>, <span class="extract"><span class="extract-syntax">a.b(c)</span></span>, <span class="extract"><span class="extract-syntax">a.b(c, d)</span></span> or <span class="extract"><span class="extract-syntax">a.b(c, d, e)</span></span>. In effect, they look up a
|
|
property value which is a function, and call it. But because they have very
|
|
slightly different semantics from indirect function calls, they appear here
|
|
as primitives of their own. Inform 7 never compiles these, but kit assimilation
|
|
may do. To get an idea of how to handle these, see for example
|
|
<a href="../final-module/5-cfm.html" class="internal">C Function Model (in final)</a>, which compiles them to C.
|
|
</p>
|
|
|
|
<ul class="items"><li>(a) <span class="extract"><span class="extract-syntax">primitive !message0 val val -> val</span></span>.
|
|
</li><li>(b) <span class="extract"><span class="extract-syntax">primitive !message1 val val val -> val</span></span>.
|
|
</li><li>(c) <span class="extract"><span class="extract-syntax">primitive !message2 val val val val -> val</span></span>.
|
|
</li><li>(d) <span class="extract"><span class="extract-syntax">primitive !message3 val val val val val -> val</span></span>.
|
|
</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP13" class="paragraph-anchor"></a><b>§13. External function calls. </b>The following calls a function which is not part of the program itself, and
|
|
which is assumed to be provided by code written in a different programming
|
|
language. It cannot be used when Inter is being generated to Inform 6
|
|
code, because I6 has no ability to link with external code; but it can be
|
|
used when generating C, for example.
|
|
</p>
|
|
|
|
<p class="commentary">The first value must be a literal double-quoted text, and is the name of
|
|
the external function. The second value is an argument to pass to it; and
|
|
the result is whatever value it returns.
|
|
</p>
|
|
|
|
<ul class="items"><li>(a) <span class="extract"><span class="extract-syntax">primitive !externalcall val val -> val</span></span>.
|
|
</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP14" class="paragraph-anchor"></a><b>§14. Control flow. </b>The simplest control statement is an "if". Note that a different primitive
|
|
is used if there is an "else" attached: it would be impossible to use the
|
|
same primitive for both because they couldn't have the same signature.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="extract"><span class="extract-syntax">!ifdebug</span></span> is an oddity: it executes the code only if the program is
|
|
being compiled in "debugging mode". (In Inform, that would mean that the
|
|
story file is being made inside the application, or else released in a
|
|
special testing configuration.) While the same effect could be achieved
|
|
using conditional compliation splats, this is much more efficient.
|
|
Similarly for <span class="extract"><span class="extract-syntax">!ifstrict</span></span>, which tests for "strict mode", in which run-time
|
|
checking of program correctness is performed, but at some performance cost.
|
|
</p>
|
|
|
|
<ul class="items"><li>(a) <span class="extract"><span class="extract-syntax">primitive !if val code -> void</span></span>.
|
|
</li><li>(b) <span class="extract"><span class="extract-syntax">primitive !ifelse val code code -> void</span></span>.
|
|
</li><li>(c) <span class="extract"><span class="extract-syntax">primitive !ifdebug code -> void</span></span>.
|
|
</li><li>(d) <span class="extract"><span class="extract-syntax">primitive !ifstrict code -> void</span></span>.
|
|
</li></ul>
|
|
<p class="commentary">There are then several loops.
|
|
</p>
|
|
|
|
<ul class="items"><li>(a) <span class="extract"><span class="extract-syntax">primitive !while val code -> void</span></span>. Similar to <span class="extract"><span class="extract-syntax">while</span></span> in C.
|
|
</li><li>(b) <span class="extract"><span class="extract-syntax">primitive !do val code -> void</span></span>. A do/until loop, where the test of <span class="extract"><span class="extract-syntax">val</span></span>
|
|
comes at the end of each iteration. Note that this is do/until, not do/while.
|
|
</li><li>(c) <span class="extract"><span class="extract-syntax">primitive !for val val val code -> void</span></span>. Similar to <span class="extract"><span class="extract-syntax">for</span></span> in C.
|
|
</li><li>(d) <span class="extract"><span class="extract-syntax">primitive !objectloopx ref val code -> void</span></span>. A loop over instances,
|
|
stored in the variable <span class="extract"><span class="extract-syntax">ref</span></span>, of the kind of object <span class="extract"><span class="extract-syntax">val</span></span>.
|
|
</li><li>(e) <span class="extract"><span class="extract-syntax">primitive !objectloop ref val val code -> void</span></span>. A more general form,
|
|
where the second <span class="extract"><span class="extract-syntax">val</span></span> is a condition to be evaluated which decides whether
|
|
to execute the code for given <span class="extract"><span class="extract-syntax">ref</span></span> value.
|
|
</li></ul>
|
|
<p class="commentary">A switch statement takes a value, and then executes at most one of an
|
|
arbitrary number of possible code segments. This can't be implemented with
|
|
a single primitive, because its signature would have to be of varying
|
|
lengths with different uses (since some switches have many cases, some few).
|
|
Instead: a <span class="extract"><span class="extract-syntax">switch</span></span> takes a single <span class="extract"><span class="extract-syntax">code</span></span>, but that <span class="extract"><span class="extract-syntax">code</span></span> can in turn
|
|
contain only invocations of <span class="extract"><span class="extract-syntax">!case</span></span>, followed optionally by one of <span class="extract"><span class="extract-syntax">!default</span></span>.
|
|
</p>
|
|
|
|
<ul class="items"><li>(a) <span class="extract"><span class="extract-syntax">primitive !switch val code -> void</span></span>.
|
|
</li><li>(b) <span class="extract"><span class="extract-syntax">primitive !case val code -> void</span></span>.
|
|
</li><li>(c) <span class="extract"><span class="extract-syntax">primitive !default code -> void</span></span>.
|
|
</li><li>(d) <span class="extract"><span class="extract-syntax">primitive !alternativecase val val -> val</span></span>.
|
|
</li></ul>
|
|
<p class="commentary">This looks a little baroque, but it works in practice:
|
|
</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">!switch</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">code</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">inv</span><span class="plain-syntax"> </span><span class="function-syntax">!case</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">1</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">"One!"</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">inv</span><span class="plain-syntax"> </span><span class="function-syntax">!case</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">inv</span><span class="plain-syntax"> </span><span class="function-syntax">!alternativecase</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">7</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">"Either two or seven!"</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">inv</span><span class="plain-syntax"> </span><span class="function-syntax">!default</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">"Something else!"</span>
|
|
</pre>
|
|
<p class="commentary">As in most C-like languages, there are primitives for:
|
|
</p>
|
|
|
|
<ul class="items"><li>(a) <span class="extract"><span class="extract-syntax">primitive !break void -> void</span></span>. Exit the innermost switch case or loop.
|
|
</li><li>(b) <span class="extract"><span class="extract-syntax">primitive !continue void -> void</span></span>. Complete the current iteration of
|
|
the innermost loop.
|
|
</li></ul>
|
|
<p class="commentary">Two ways to terminate what's happening:
|
|
</p>
|
|
|
|
<ul class="items"><li>(a) <span class="extract"><span class="extract-syntax">primitive !return val -> void</span></span>. Finish the current function, giving the
|
|
supplied value as the result if the function is being executed in a value
|
|
context, and throwing it away if not.
|
|
</li><li>(b) <span class="extract"><span class="extract-syntax">primitive !quit void -> void</span></span>. Halt the whole program immediately.
|
|
</li></ul>
|
|
<p class="commentary">This is a sort of termination, too, loading in a fresh program state from a
|
|
file; something which may not be very meaningful in all platforms. Note that
|
|
there is no analogous <span class="extract"><span class="extract-syntax">!restart</span></span> or <span class="extract"><span class="extract-syntax">!save</span></span> primitive: those are handled by
|
|
assembly language instead. This may eventually go, too.
|
|
</p>
|
|
|
|
<ul class="items"><li>(a) <span class="extract"><span class="extract-syntax">primitive !restore lab -> void</span></span>.
|
|
</li></ul>
|
|
<p class="commentary">And, lastly, the lowest-level way to travel:
|
|
</p>
|
|
|
|
<ul class="items"><li>(a) <span class="extract"><span class="extract-syntax">primitive !jump lab -> void</span></span>. Jump to this label in the current function.
|
|
</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP15" class="paragraph-anchor"></a><b>§15. Interactive fiction-only primitives. </b>The following would make no sense in a general-purpose program. Most mirror
|
|
very low-level I6 features. First, the spatial containment object tree:
|
|
</p>
|
|
|
|
<ul class="items"><li>(a) <span class="extract"><span class="extract-syntax">primitive !move val val -> void</span></span>. Moves first to second (both are objects).
|
|
</li><li>(b) <span class="extract"><span class="extract-syntax">primitive !remove val -> void</span></span>. Removes object from containment tree.
|
|
</li><li>(c) <span class="extract"><span class="extract-syntax">primitive !in val val -> val</span></span>. Tests if first is in second (both are objects).
|
|
</li><li>(d) <span class="extract"><span class="extract-syntax">primitive !notin val val -> val</span></span>. Negation of same.
|
|
</li><li>(e) <span class="extract"><span class="extract-syntax">primitive !child val -> val</span></span>. Finds the child node of an object.
|
|
</li><li>(f) <span class="extract"><span class="extract-syntax">primitive !children val -> val</span></span>. The number of children: which may be 0.
|
|
</li><li>(g) <span class="extract"><span class="extract-syntax">primitive !parent val -> val</span></span>. Finds the parent of an object.
|
|
</li><li>(h) <span class="extract"><span class="extract-syntax">primitive !sibling val -> val</span></span>. Finds the sibling of an object.
|
|
</li></ul>
|
|
<p class="commentary">Object class membership:
|
|
</p>
|
|
|
|
<ul class="items"><li>(a) <span class="extract"><span class="extract-syntax">primitive !ofclass val val -> val</span></span>. Does the first belong to the enumerated
|
|
subkind whose weak type ID is the second value?
|
|
</li><li>(b) <span class="extract"><span class="extract-syntax">primitive !metaclass val -> val</span></span>. Returns <span class="extract"><span class="extract-syntax">Class</span></span>, <span class="extract"><span class="extract-syntax">Object</span></span>, <span class="extract"><span class="extract-syntax">Routine</span></span>,
|
|
<span class="extract"><span class="extract-syntax">String</span></span> or 0 depending on the value supplied: see the Inform 6 Designer's Manual
|
|
for more on this.
|
|
</li></ul>
|
|
<nav role="progress"><div class="progresscontainer">
|
|
<ul class="progressbar"><li class="progressprev"><a href="M-cpiti.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="progresssection"><a href="M-cpiti.html">cpiti</a></li><li class="progresscurrent">ip</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-ia.html">❯</a></li></ul></div>
|
|
</nav><!--End of weave-->
|
|
|
|
</main>
|
|
</body>
|
|
</html>
|
|
|