--- /dev/null
+===============================
+ Appendix E -- Inform language
+===============================
+
+.. default-role:: samp
+
+.. only:: html
+
+ .. image:: /images/picR.png
+ :align: left
+
+.. raw:: latex
+
+ \dropcap{r}
+
+efer to this appendix for a succinct but essentially complete summary of
+the Inform programming language; it covers everything that we've met in
+this guide, plus various constructs which didn't occur naturally, and
+others of an advanced or obscure nature.
+
+Literals
+========
+
+In the specialised language of computing, the basic unit of data storage is
+an eight-bit **byte**, able to store a value 0..255. That's too small to
+be useful for holding anything other than a single character, so most
+computers also work with a group of two, four or eight bytes known as a
+**word** (not to be confused with Inform's dictionary word). In the
+Z-machine a storage word comprises two bytes, and you can specify in
+various ways the literal values to be stored.
+
+:Decimal: `-32768` to `32767`
+:Hexadecimal: `$0` to `$FFFF`
+:Binary: `$$0` to `$$1111111111111111`
+:Action: `##Look`
+:Character: `'a'`
+:Dictionary word: `'aardvark'` (up to nine characters significant); use
+ circumflex "^" to denote apostrophe.
+
+:Plural word: `'aardvarks//p'`
+
+:Single-character word: `"a"` (`name` property only) or `'a//'`
+:String: `"aardvark's adventure"` (maximum around 4000 characters); can
+ include special values including:
+
+ ============= ====================================
+ `^` newline
+ `~` double quotes "`\"`"
+ `@@64` at sign "`@`"
+ `@@92` backslash "`\\`"
+ `@@94` circumflex "`^`"
+ `@@126` tilde "`~`"
+ `@\`a` a with a grave accent "`à`", et al
+ `@LL` pound sign "`£`", et al
+ `@00 ... @31` low string 0..31
+ ============= ====================================
+
+Names
+=====
+
+The identifier of an Inform `{const_id}`, `{var_id}`, `{array}`,
+`{class_id}`, `{obj_id}`, `{property}`, `{attribute}`, `{routine_id}` or
+`{label}`. Up to 32 characters: alphabetic (case not significant), numeric
+and underscore, with the first character not a digit.
+
+Constants
+=========
+
+Named word values, unchanging at run-time, which are by default initialised
+to zero:
+
+ | `Constant {const_id}`;
+ | `Constant {const_id} = {expr}`;
+
+Standard constants are `true` (1), `false` (0) and `nothing` (0), also
+`NULL` (-1). Additionally, `WORDSIZE` is the number of bytes in a storage
+word: 2 for the Z-machine, 4 for Glulx.
+
+To define a constant (unless it already exists):
+
+ | `Default {const_id expr}`;
+
+Variables and arrays
+====================
+
+Named word/byte values which can change at run-time and are by default
+initialised to zero.
+
+A **global** variable is a single word:
+
+ | `Global {var_id}`;
+ | `Global {var_id} = {expr}`;
+
+A **word array** is a set of global words accessed using
+`{array}->0,{array}->1,... {array}->({N}-1)`:
+
+ | `Array {array} --> {N};`
+ | `Array {array} --> {expr1 expr2... exprN};`
+ | `Array {array} --> "{string}";`
+
+A **table array** is a set of global words accessed using `{array}->1,
+{array}->2,... {array}->{N}`, with `{array}->0` initialised to `{N}`:
+
+ | `Array {array} table {N};`
+ | `Array {array} table {expr1... exprN};`
+ | `Array {array} table "{string}";`
+
+A **byte array** is a set of global bytes accessed using `{array}->0,
+{array}->1,... {array}->({N}-1)`:
+
+ | `Array {array} -> {N};`
+ | `Array {array} -> {expr1 expr2... exprN};`
+ | `Array {array} -> "{string}";`
+
+A **string array** is a set of global bytes accessed using `array->1,
+array->2,... array->{N}`, with `array->0` initialised to `{N}`:
+
+ | `Array {array} string {N};`
+ | `Array {array} string {expr1... exprN};`
+ | `Array {array} string "{string}";`
+
+A **buffer array** is a set of global bytes accessed using
+`{array}->(WORDSIZE), {array}->(WORDSIZE+1), ...
+{array}->(WORDSIZE+{N}-1)`, with the first **word** `{array}->0`
+initialised to `{N}`:
+
+ | `Array {array} buffer {N};`
+ | `Array {array} buffer {expr1... exprN};`
+ | `Array {array} buffer "{string}";`
+
+In all these cases, the characters of the initialising `{string}` are
+unpacked to the individual word/byte elements of the array.
+
+See also Objects (for **property** variables) and Routines (for **local**
+variables).
+
+Expressions and operators
+=========================
+
+Use parentheses `(...)` to control the order of evaluation.
+
+Arithmetic/logical expressions support these operators:
+
+ =========== ====================================
+ `{p} + {q}` addition
+ `{p} - {q}` subtraction
+ `{p} * {q}` multiplication
+ `{p} / {q}` integer division
+ `{p} % {q}` remainder
+ `{p}++` increments `{p}`, returns orig value
+ `++{p}` increments `{p}`, returns new value
+ `{p}--` decrements `{p}`, returns orig value
+ `--{p}` decrements `{p}`, returns new value
+ `{p} & {q}` bitwise AND
+ `{p} | {q}` bitwise OR
+ `~{p}` bitwise NOT (inversion)
+ =========== ====================================
+
+Conditional expressions return `true` or `false`; `{q}` may be a list of
+choices `{q1} or {q2} or ... {qN}`:
+
+ ================== ==========================================
+ `{p} == {q}` `{p}` is equal to `{q}`
+ `{p} ~= {q}` `{p}` isn't equal to `{q}`
+ `{p} > {q}` `{p}` is greater than `{q}`
+ `{p} < {q}` `{p}` is less than `{q}`
+ `{p} >= {q}` `{p}` is greater than or equal to `{q}`
+ `{p} <= {q}` `{p}` is less than or equal to `{q}`
+ `{p} ofclass {q}` object `{p}` is of class `{q}`
+ `{p} in {q}` object `{p}` is a child of object `{q}`
+ `{p} notin {q}` object `{p}` isn't a child of object `{q}`
+ `{p} provides {q}` object `{p}` provides property `{q}`
+ `{p} has {q}` object `{p}` has attribute `{q}`
+ `{p} hasnt {q}` object `{p}` hasn't attribute `{q}`
+ ================== ==========================================
+
+Boolean expressions return `true` or `false`; if `{p}` has determined the
+result, `{q}` is not evaluated:
+
+ ============ ========================================
+ `{p} && {q}` both `{p}` and `{q}` are true (non-zero)
+ `{p} || {q}` either `{p}` or `{q}` is true (non-zero)
+ `~~{p}` `{p}` is false (zero)
+ ============ ========================================
+
+To return -1, 0 or 1 based on unsigned comparison:
+
+ | `UnsignedCompare({p},{q})`
+
+To return `true` if object `{q}` is a child or grandchild or... of `{p}`:
+
+ | `IndirectlyContains({p},{q})`
+
+To return the closest common parent of two objects (or nothing):
+
+ | `CommonAncestor({p},{q})`
+
+To return a random number `1..{N}`, or one from a list of constant values:
+
+ | `random({N})`
+ | `random({value,value, ... value})`
+
+Classes and objects
+===================
+
+To declare a `{class_id}` - a template for a family of objects - where the
+optional (`{N}`) limits instances created at run-time:
+
+ | `Class {class_id}({N})`
+ | `class {class_id} {class_id}... {class_id}`
+ | `with {prop_def},`
+ | `...`
+ | `{prop_def},`
+ | `has {attr_def} {attr_def}... {attr_def};`
+
+To declare an `{obj_id}`, "`Object`" can instead be a `{class_id}`, the
+remaining four header items are all optional, and `{arrows}` (`->`, `->
+->`, ...) and `{parent_obj_id}` are incompatible:
+
+ | `Object {arrows obj_id} "{ext_name}" {parent_obj_id}`
+ | `class {class_id} {class_id}... {class_id}`
+ | `with {prop_def},`
+ | `...`
+ | `{prop_def},`
+ | `has {attr_def} {attr_def}... {attr_def};`
+
+The `class`, `with` and `has` (and also the rarely-used `private`) segments
+are all optional, and can appear in any order.
+
+To determine an object's class as one of `Class`, `Object`, `Routine`,
+`String` (or `nothing`):
+
+ | `metaclass({obj_id})`
+
+**has segment**: Each `{attr_def}` is either of:
+
+ | `{attribute}`
+ | `~{attribute}`
+
+To change attributes at run-time:
+
+ | `give {obj_id attr_def... attr_def};`
+
+**with/private segments**: Each `{prop_def}` declares a variable (or word
+array) and can take any of these forms (where a `{value}` is an expression,
+a string or an embedded routine):
+
+ | `{property}`
+ | `{property value}`
+ | `{property value value... value}`
+
+A property variable is addressed by `{obj_id.property}` (or within the
+object's declaration as `{self.property}`).
+
+Multiple `{values}` create a property array; in this case
+`{obj_id.#property}` is the number of bytes occupied by the array, the
+entries can be accessed using `{obj_id.&property}-->0`,
+`{obj_id.&property}->1`, ..., and `{obj_id.property}` refers to the value
+of the first entry.
+
+A property variable inherited from an object's class is addressed by
+`{obj_id.class_id}::{property}`; this gives the original value prior to any
+changes within the object.
+
+Manipulating the object tree
+============================
+
+To change object relationships at run-time:
+
+ | `move {obj_id} to {parent_obj_id};`
+ | `remove {obj_id};`
+
+To return the parent of an object (or nothing):
+
+ | `parent({obj_id})`
+
+To return the first child of an object (or nothing):
+
+ | `child({obj_id})`
+
+To return the adjacent child of an object's parent (or nothing):
+
+ | `sibling({obj_id})`
+
+To return the number of child objects directly below an object:
+
+ | `children({obj_id})`
+
+Message passing
+===============
+
+To a class:
+
+ | `{class_id}.remaining()`
+ | `{class_id}.create()`
+ | `{class_id}.destroy({obj_id})`
+ | `{class_id}.recreate({obj_id})`
+ | `{class_id}.copy({to_obj_id},{from_obj_id})`
+
+To an object:
+
+ | `{obj_id.property(a1,a2, ... a7)}`
+
+To a routine:
+
+ | `{routine_id}.call({a1,a2, ... a7})`
+
+To a string:
+
+ | `{string}.print()`
+ | `{string}.print_to_array({array})`
+
+Uncommon and deprecated statements
+==================================
+
+To jump to a labelled statement:
+
+ | `jump {label};`
+ | `...`
+ | `.{label}; {statement};`
+
+To terminate the program:
+
+ | `quit;`
+
+To save and restore the program state:
+
+ | `save {label};`
+ | `...`
+ | `restore {label};`
+
+To output the Inform compiler version number:
+
+ | `inversion;`
+
+To accept data from the current input stream:
+
+ | `read {text_array parse_array routine_id};`
+
+To assign to one of 32 'low string' variables:
+
+ | `string {N} "{string}";`
+ | `Lowstring {string_var} "{string}";`
+ | `string {N string_var};`
+
+Statements
+==========
+
+Each `{statement}` is terminated by a semicolon "`;`".
+
+A `{statement_block}` is a single `{statement}` or a series of
+`{statements}` enclosed in braces ``{...}``.
+
+An exclamation "`!`" starts a comment - the rest of the line is ignored.
+
+A common statement is the assignment:
+
+ | `{var_id} = {expr};`
+
+There are two forms of multiple assignment:
+
+ | `{var_id} = {var_id} = ... = {expr};`
+ | `{var_id} = {expr}, {var_id} = {expr}, ... ;`
+
+Routines
+========
+
+A routine can have up to 15 **local variables**: word values which are
+private to the routine and which by default are set to zero on each call.
+
+Recursion is permitted.
+
+A **standalone** routine:
+
+* has a name, by which it is called using `{routine_id}();` can also be
+ called indirectly using `indirect({routine_id,a1,a2, ... a7})`
+
+* can take arguments, using `{routine_id}({a1,a2, ... a7})`, whose values
+ initialise the equivalent local variables
+
+* returns `true` at the final "`]`"
+
+ | `[ {routine_id}`
+ | `{local_var} {local_var}... {local_var};`
+ | `{statement};`
+ | `{statement};`
+ | `...`
+ | `{statement};`
+ | `];`
+
+A routine **embedded** as the value of an object property:
+
+* has no name, and is called when the property is invoked; can also be
+ called explicitly using `{obj_id.property}()`
+
+* accepts arguments only when called explicitly
+
+* returns `false` at the final "`]`"
+
+ | `property [`
+ | `{local_var} {local_var}... {local_var};`
+ | `{statement};`
+ | `{statement};`
+ | `...`
+ | `{statement};`
+ | `]`
+
+Routines return a single value, when execution reaches the final "`]`" or
+an explicit `return` statement:
+
+ | `return {expr};`
+ | `return;`
+ | `rtrue;`
+ | `rfalse;`
+
+Flow control
+============
+
+To execute statements if `{expr}` is `true`; optionally, to execute other
+statements if `{expr}` is `false`:
+
+ | `if ({expr})`
+ | `{statement_block}`
+ |
+ | `if ({expr})`
+ | `{statement_block}`
+ | `else`
+ | `{statement_block}`
+
+To execute statements depending on the value of `{expr}`:
+
+ | `switch ({expr}) {`
+ | `{value}: {statement};... {statement};`
+ | `{value}: {statement};... {statement};`
+ | `...`
+ | `default: {statement};... {statement};`
+ | `}`
+
+where each `{value}` can be given as:
+
+ | `{constant}`
+ | `{lo_constant} to {hi_constant}`
+ | `{constant,constant,... constant}`
+
+And, if you really must:
+
+ | `jump {label};`
+ | `...`
+ | `.{label}; {statement};`
+
+Loop control
+============
+
+To execute statements while `{expr}` is true:
+
+ | `while ({expr})`
+ | `{statement_block}`
+
+To execute statements until `{expr}` is true:
+
+ | `do`
+ | `{statement_block}`
+ | `until ({expr})`
+
+To execute statements while a variable changes:
+
+ | `for ({set_var} : {loop_while_expr} : {update_var})`
+ | `{statement_block}`
+
+To execute statements for all defined objects:
+
+ | `objectloop ({var_id})`
+ | `{statement_block}`
+
+To execute statements for all objects selected by `{expr}`:
+
+ | `objectloop ({expr_starting_with_var})`
+ | `{statement_block}`
+
+To jump out of the current innermost loop or switch:
+
+ | `break;`
+
+To immediately start the next iteration of the current loop:
+
+ | `continue;`
+
+Displaying information
+======================
+
+To output a list of values:
+
+ | `print {value},{value},... {value};`
+
+To output a list of values followed by a newline, then return `true` from
+the current routine:
+
+ | `print_ret {value},{value},... {value};`
+
+If the first (or only) `{value}` is a string, "`print_ret`" can be
+omitted:
+
+ | `"{string}",{value}, ... {value};`
+
+Each `{value}` can be an expression, a string or a rule.
+
+An **expression** is output as a signed decimal value.
+
+A **string** in quotes "`...`" is output as text.
+
+A **rule** is one of:
+
+ ======================== ===============================================
+ `(number) {expr}` the `{expr}` in words
+ `(char) {expr}` the `{expr}` as a single character
+ `(string) {addr}` the string at the `{addr}`
+ `(address) {addr}` the dictionary word at the `{addr}`
+ `(name) {obj_id}` the external (short) name of the `{obj_id}`
+ `(a) {obj_id}` the short name preceded by "`a/an`",
+ by "`some`", or by nothing for proper nouns
+ `(A) {obj_id}` the short name preceded by "`A/An`",
+ by "`Some`", or by nothing for proper nouns
+ `(the) {obj_id}` the short name preceded by "`the`"
+ `(The) {obj_id}` the short name preceded by "`The`"
+ `({routine_id}){value}` the output when calling `{routine_id}({value})`
+ ======================== ===============================================
+
+To output a newline character:
+
+ | `new_line;`
+
+To output multiple spaces:
+
+ | `spaces {expr};`
+
+To output text in a display box:
+
+ | `box "{string}" "{string}"... "{string}";`
+
+To change from regular to fixed-pitch font:
+
+ | `font off;`
+ | `...`
+ | `font on;`
+
+To change the font attributes:
+
+ | `style bold; ! use any of these`
+ | `style underline; !`
+ | `style reverse; !`
+ | `...`
+ | `style roman;`
+
+Verbs and actions
+=================
+
+To specify a new verb:
+
+ | `Verb '{verb}' '{verb}'... '{verb}'`
+ | `* {token} {token}... {token} -> {action}`
+ | `* {token} {token}... {token} -> {action}`
+ | `...`
+ | `* {token} {token}... {token} -> {action}`
+
+where instead "`Verb`" can be "`Verb meta`", "`{action}`" can be "`{action
+reverse}`"; `{tokens}` are optional and each is one of:
+
+ ==================== ==================================================
+ `'{word}'` that literal word
+ `'{w1}'/'{w2}'/...` any one of those literal words
+ `{attribute}` an object with that attribute
+ `creature` an object with `animate` attribute
+ `held` an object held by the player
+ `noun` an object in scope
+ `noun={routine_id}` an object for which `{routine_id}` returns `true`
+ `scope={routine_id}` an object in this re-definition of scope
+ `multiheld` one or more objects held by the player
+ `multi` one or more objects in scope
+ `multiexcept` as `multi`, omitting the specified object
+ `multiinside` as `multi`, omitting those in specified object
+ `topic` any text
+ `number` any number
+ `{routine_id}` a general parsing routine
+ ==================== ==================================================
+
+To add synonyms to an existing verb:
+
+ | `Verb '{verb}' '{verb}'... =`
+ | `'{existing_verb}';`
+
+To modify an existing verb:
+
+ | `Extend '{existing_verb}' last`
+ | `* {token} {token}... {token} -> {action}`
+ | `* {token} {token}... {token} -> {action}`
+ | `...`
+ | `* {token} {token}... {token} -> {action}`
+
+where instead "`Extend`" can be "`Extend only`" and "`last`" can be
+omitted, or changed to "`first`" or "`replace`".
+
+To explicitly trigger a defined action (both `{noun}` and `{second}` are
+optional, depending on the `{action}`):
+
+ | `<{action noun second}>;`
+
+To explicitly trigger a defined action, then return `true` from the current
+routine:
+
+ | `<<{action noun second}>>;`
+
+Other useful directives
+=======================
+
+To set compiler switches *at the very start* of the source file:
+
+ | `!% {list_of_compiler_switches};`
+
+To include a directive within a routine definition `[...]`, insert a hash
+"`#`" as its first character.
+
+To conditionally compile:
+
+ | `Ifdef {name}; ! use any one of these`
+ | `Ifndef {name}; !`
+ | `Iftrue {expr}; !`
+ | `Iffalse {expr}; !`
+ | `...`
+ | `Ifnot;`
+ | `...`
+ | `Endif;`
+
+To display a compile-time message:
+
+ | `Message "{string}";`
+
+To include the contents of a file, searching the Library path:
+
+ | `Include "{source_file}";`
+
+To include the contents of a file in the same location as the current
+file:
+
+ | `Include ">{source_file}";`
+
+To specify that a library routine is to be replaced:
+
+ | `Replace {routine_id};`
+
+To set the game's release number (default is 1), serial number (default is
+today's `{yymmdd}`) and status line format (default is `score`):
+
+ | `Release {expr};`
+ | `Serial "{yymmdd}";`
+ | `Statusline score;`
+ | `Statusline time;`
+
+To declare a new attribute common to all objects:
+
+ | `Attribute {attribute};`
+
+To declare a new property common to all objects:
+
+ | `Property {property};`
+ | `Property {property expr};`
+
+Uncommon and deprecated directives
+==================================
+
+You're unlikely to need these; look them up in the *Designer's Manual* if
+necessary.
+
+ | `Abbreviate "{string}"... "{string}";`
+ | `End;`
+ | `Import {var_id var_id} ... {var_id};`
+ | `Link "{compiled_file}";`
+ | `Stub {routine_id N};`
+ | `Switches {list_of_compiler_switches};`
+ | `System_file;`