<pclass="commentary firstcommentary"><aid="SP1"class="paragraph-anchor"></a><b>§1. What standard means. </b>To recap from <ahref="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 <ahref="../building-module/index.html"class="internal">building</a> module of Inter defines a standard set of 95 or so primitives
<ulclass="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>
<pclass="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>
<pclass="commentary">(See <ahref="../building-module/1-ip.html"class="internal">Inter Primitives (in building)</a> for where in the <ahref="index.html"class="internal">inter</a> source code
<pclass="commentary firstcommentary"><aid="SP2"class="paragraph-anchor"></a><b>§2. Arithmetic. </b>The following are standard integer arithmetic operations, using signed
<ulclass="items"><li>(a) <spanclass="extract"><spanclass="extract-syntax">primitive !plus val val -> val</span></span>. 16 or 32-bit integer addition.
</li><li>(b) <spanclass="extract"><spanclass="extract-syntax">primitive !minus val val -> val</span></span>. 16 or 32-bit integer subtraction.
</li><li>(c) <spanclass="extract"><spanclass="extract-syntax">primitive !unaryminus val -> val</span></span>. Equivalent to performing <spanclass="extract"><spanclass="extract-syntax">0 - x</span></span>.
</li><li>(d) <spanclass="extract"><spanclass="extract-syntax">primitive !times val val -> val</span></span>. 16 or 32-bit integer multiplication.
</li><li>(e) <spanclass="extract"><spanclass="extract-syntax">primitive !divide val val -> val</span></span>. 16 or 32-bit integer division.
</li><li>(f) <spanclass="extract"><spanclass="extract-syntax">primitive !modulo val val -> val</span></span>. Remainder after such a division.
<pclass="commentary firstcommentary"><aid="SP3"class="paragraph-anchor"></a><b>§3. Logical operators. </b>In general, the value 0 is false, and all other values are true.
<ulclass="items"><li>(a) <spanclass="extract"><spanclass="extract-syntax">primitive !not val -> val</span></span>. True if the value is false, and vice versa.
</li><li>(b) <spanclass="extract"><spanclass="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) <spanclass="extract"><spanclass="extract-syntax">primitive !or val val -> val</span></span>. True if either is true: doesn't evaluate the
<pclass="commentary firstcommentary"><aid="SP4"class="paragraph-anchor"></a><b>§4. Bitwise operators. </b>These differ in that they do not "short circuit", and do not squash values
<pclass="commentary firstcommentary"><aid="SP5"class="paragraph-anchor"></a><b>§5. Numerical comparison. </b>These are comparisons of signed integers. (If Inform needs to compare unsigned
<pclass="commentary firstcommentary"><aid="SP6"class="paragraph-anchor"></a><b>§6. Sequential evaluation. </b>The reason for the existence of <spanclass="extract"><spanclass="extract-syntax">!ternarysequential</span></span> is that it's a convenient
<ulclass="items"><li>(a) <spanclass="extract"><spanclass="extract-syntax">primitive !sequential val val -> val</span></span>. Evaluates the first, then the second
<pclass="commentary firstcommentary"><aid="SP7"class="paragraph-anchor"></a><b>§7. Random. </b>This is essentially the built-in <spanclass="extract"><spanclass="extract-syntax">random</span></span> function of Inform 6, given an Inter
disguise. See the Inform 6 Designer's Manual for a specification.
</p>
<ulclass="items"><li>(a) <spanclass="extract"><spanclass="extract-syntax">!primitive random val -> val</span></span>.
</li></ul>
<pclass="commentary firstcommentary"><aid="SP8"class="paragraph-anchor"></a><b>§8. Printing. </b>These print data of various kinds:
</li><li>(c) <spanclass="extract"><spanclass="extract-syntax">primitive !printchar val -> void</span></span>. Print a character value.
</li><li>(d) <spanclass="extract"><spanclass="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) <spanclass="extract"><spanclass="extract-syntax">primitive !printdword val -> void</span></span>. Print a dictionary word.
</li><li>(f) <spanclass="extract"><spanclass="extract-syntax">primitive !printstring val -> void</span></span>. Print a packed string.
<ulclass="items"><li>(a) <spanclass="extract"><spanclass="extract-syntax">primitive !font val -> void</span></span>. Change to fixed-width font if value is 1, or regular if 0.
<pclass="commentary firstcommentary"><aid="SP9"class="paragraph-anchor"></a><b>§9. Stack access. </b>The stack is not directly accessible anywhere in memory, so the only access
<ulclass="items"><li>(a) <spanclass="extract"><spanclass="extract-syntax">primitive !push val -> void</span></span>. Push value onto the stack.
</li><li>(b) <spanclass="extract"><spanclass="extract-syntax">primitive !pull ref -> void</span></span>. Pull value from the stack and write it into
<pclass="commentary firstcommentary"><aid="SP10"class="paragraph-anchor"></a><b>§10. Accessing storage. </b>Here the <spanclass="extract"><spanclass="extract-syntax">ref</span></span> term is a refernce to a piece of storage: a property of an
<ulclass="items"><li>(a) <spanclass="extract"><spanclass="extract-syntax">primitive !store ref val -> val</span></span>. Put the value in <spanclass="extract"><spanclass="extract-syntax">ref</span></span>.
</li><li>(b) <spanclass="extract"><spanclass="extract-syntax">primitive !setbit ref val -> void</span></span>. Set bits in the mask <spanclass="extract"><spanclass="extract-syntax">val</span></span> in <spanclass="extract"><spanclass="extract-syntax">ref</span></span>.
</li><li>(c) <spanclass="extract"><spanclass="extract-syntax">primitive !clearbit ref val -> void</span></span>. Clear bits in the mask <spanclass="extract"><spanclass="extract-syntax">val</span></span> in <spanclass="extract"><spanclass="extract-syntax">ref</span></span>.
</li><li>(d) <spanclass="extract"><spanclass="extract-syntax">primitive !postincrement ref -> val</span></span>. Performs the equivalent of <spanclass="extract"><spanclass="extract-syntax">ref++</span></span>.
</li><li>(e) <spanclass="extract"><spanclass="extract-syntax">primitive !preincrement ref -> val</span></span>. Performs the equivalent of <spanclass="extract"><spanclass="extract-syntax">++ref</span></span>.
</li><li>(f) <spanclass="extract"><spanclass="extract-syntax">primitive !postdecrement ref -> val</span></span>. Performs the equivalent of <spanclass="extract"><spanclass="extract-syntax">ref--</span></span>.
</li><li>(g) <spanclass="extract"><spanclass="extract-syntax">primitive !predecrement ref -> val</span></span>. Performs the equivalent of <spanclass="extract"><spanclass="extract-syntax">--ref</span></span>.
<ulclass="items"><li>(a) <spanclass="extract"><spanclass="extract-syntax">primitive !lookup val val -> val</span></span>. Find word at this word offset.
</li><li>(b) <spanclass="extract"><spanclass="extract-syntax">primitive !lookupbyte val val -> val</span></span>. Find byte at this byte offset.
<pclass="commentary">Properties, like memory, can be converted to <spanclass="extract"><spanclass="extract-syntax">ref</span></span> in order to write to them,
and are accessible with <spanclass="extract"><spanclass="extract-syntax">propertyvalue</span></span>. Their existence can be tested with
<spanclass="extract"><spanclass="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 <spanclass="extract"><spanclass="extract-syntax">K</span></span>, the
weak kind ID of the owner; <spanclass="extract"><spanclass="extract-syntax">O</span></span>, the owner; and <spanclass="extract"><spanclass="extract-syntax">P</span></span>, the property. For properties
of objects, <spanclass="extract"><spanclass="extract-syntax">K</span></span> will always be <spanclass="extract"><spanclass="extract-syntax">OBJECT_TY</span></span>.
</p>
<pclass="commentary"><spanclass="extract"><spanclass="extract-syntax">propertyarray</span></span> and <spanclass="extract"><spanclass="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 <spanclass="extract"><spanclass="extract-syntax">O</span></span> is not an object, since
only objects can have inline property values.
</p>
<ulclass="items"><li>(a) <spanclass="extract"><spanclass="extract-syntax">primitive !propertyvalue val val val -> val</span></span>.
</li><li>(b) <spanclass="extract"><spanclass="extract-syntax">primitive !propertyarray val val val -> val</span></span>.
</li><li>(c) <spanclass="extract"><spanclass="extract-syntax">primitive !propertylength val val val -> val</span></span>.
</li><li>(d) <spanclass="extract"><spanclass="extract-syntax">primitive !propertyexists val val val -> val</span></span>.
<pclass="commentary firstcommentary"><aid="SP11"class="paragraph-anchor"></a><b>§11. Indirect function calls. </b>Invocations of functions can only be made with <spanclass="extract"><spanclass="extract-syntax">inv</span></span> when the function is
<pclass="commentary firstcommentary"><aid="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
<spanclass="extract"><spanclass="extract-syntax">a.b()</span></span>, <spanclass="extract"><spanclass="extract-syntax">a.b(c)</span></span>, <spanclass="extract"><spanclass="extract-syntax">a.b(c, d)</span></span> or <spanclass="extract"><spanclass="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
<ahref="../final-module/5-cfm.html"class="internal">C Function Model (in final)</a>, which compiles them to C.
</p>
<ulclass="items"><li>(a) <spanclass="extract"><spanclass="extract-syntax">primitive !message0 val val -> val</span></span>.
</li><li>(b) <spanclass="extract"><spanclass="extract-syntax">primitive !message1 val val val -> val</span></span>.
</li><li>(c) <spanclass="extract"><spanclass="extract-syntax">primitive !message2 val val val val -> val</span></span>.
</li><li>(d) <spanclass="extract"><spanclass="extract-syntax">primitive !message3 val val val val val -> val</span></span>.
</li></ul>
<pclass="commentary firstcommentary"><aid="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
<pclass="commentary firstcommentary"><aid="SP14"class="paragraph-anchor"></a><b>§14. Control flow. </b>The simplest control statement is an "if". Note that a different primitive
<ulclass="items"><li>(a) <spanclass="extract"><spanclass="extract-syntax">primitive !while val code -> void</span></span>. Similar to <spanclass="extract"><spanclass="extract-syntax">while</span></span> in C.
</li><li>(b) <spanclass="extract"><spanclass="extract-syntax">primitive !do val code -> void</span></span>. A do/until loop, where the test of <spanclass="extract"><spanclass="extract-syntax">val</span></span>
comes at the end of each iteration. Note that this is do/until, not do/while.
</li><li>(c) <spanclass="extract"><spanclass="extract-syntax">primitive !for val val val code -> void</span></span>. Similar to <spanclass="extract"><spanclass="extract-syntax">for</span></span> in C.
</li><li>(d) <spanclass="extract"><spanclass="extract-syntax">primitive !objectloopx ref val code -> void</span></span>. A loop over instances,
stored in the variable <spanclass="extract"><spanclass="extract-syntax">ref</span></span>, of the kind of object <spanclass="extract"><spanclass="extract-syntax">val</span></span>.
Instead: a <spanclass="extract"><spanclass="extract-syntax">switch</span></span> takes a single <spanclass="extract"><spanclass="extract-syntax">code</span></span>, but that <spanclass="extract"><spanclass="extract-syntax">code</span></span> can in turn
contain only invocations of <spanclass="extract"><spanclass="extract-syntax">!case</span></span>, followed optionally by one of <spanclass="extract"><spanclass="extract-syntax">!default</span></span>.
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">val</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">K_text</span><spanclass="plain-syntax"></span><spanclass="string-syntax">"Either two or seven!"</span>
<ulclass="items"><li>(a) <spanclass="extract"><spanclass="extract-syntax">primitive !break void -> void</span></span>. Exit the innermost switch case or loop.
</li><li>(b) <spanclass="extract"><spanclass="extract-syntax">primitive !continue void -> void</span></span>. Complete the current iteration of
<ulclass="items"><li>(a) <spanclass="extract"><spanclass="extract-syntax">primitive !return val -> void</span></span>. Finish the current function, giving the
<pclass="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 <spanclass="extract"><spanclass="extract-syntax">!restart</span></span> or <spanclass="extract"><spanclass="extract-syntax">!save</span></span> primitive: those are handled by
assembly language instead. This may eventually go, too.
<ulclass="items"><li>(a) <spanclass="extract"><spanclass="extract-syntax">primitive !jump lab -> void</span></span>. Jumo to this label in the current function.
<pclass="commentary firstcommentary"><aid="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
<ulclass="items"><li>(a) <spanclass="extract"><spanclass="extract-syntax">primitive !move val val -> void</span></span>. Moves first to second (both are objects).
</li><li>(b) <spanclass="extract"><spanclass="extract-syntax">primitive !remove val -> void</span></span>. Removes object from containment tree.
</li><li>(c) <spanclass="extract"><spanclass="extract-syntax">primitive !in val val -> val</span></span>. Tests if first is in second (both are objects).
</li><li>(d) <spanclass="extract"><spanclass="extract-syntax">primitive !notin val val -> val</span></span>. Negation of same.
</li><li>(e) <spanclass="extract"><spanclass="extract-syntax">primitive !child val -> val</span></span>. Finds the child node of an object.
</li><li>(f) <spanclass="extract"><spanclass="extract-syntax">primitive !children val -> val</span></span>. The number of children: which may be 0.
</li><li>(g) <spanclass="extract"><spanclass="extract-syntax">primitive !parent val -> val</span></span>. Finds the parent of an object.
</li><li>(h) <spanclass="extract"><spanclass="extract-syntax">primitive !sibling val -> val</span></span>. Finds the sibling of an object.
<ulclass="items"><li>(a) <spanclass="extract"><spanclass="extract-syntax">primitive !ofclass val val -> val</span></span>. Does the first belong to the enumerated