                              Inform Release Notes

  Inform Compiler 6.30 to 6.43


Introduction

   This is a maintenance release of the Inform 6 compiler for creating
   interactive fiction. Although just about all known bugs are fixed, the
   approach to enhancing Inform is more conservative. The selection of
   suggestions to implement has been governed by two factors:
     * Avoidance of changes which might cause existing games to misbehave;
       and
     * Minimisation of features which would require updates to the Inform
       Designer’s Manual.

   Since the first release of the Inform 6.3 compiler, the Inform 6
   library has been split into a separate project, maintained at
   https://gitlab.com/DavidGriffith/inform6lib.

Acknowledgements

   Far too many people contributed towards this release — reporting and
   resolving bugs, making helpful suggestions, providing support and
   facilities, testing, and so on — for their names to be individually
   listed. So instead, this is a general thank-you to everybody who has
   made this release happen, and specific ones to Graham for permitting it
   in the first place, and to Andrew for his pioneering work on Glulx.


Compiler 6.43

   These are the changes delivered in version 6.43 of the Inform compiler.

  Features added

    * A new dictionary word flag has been introduced, "singular", which
      is set for any noun that is not a plural. This can be explicitly
      set or not set in a dictionary word with the '//s' syntax, i.e.
      'word//s' to set it, or 'word//~s' to not set it.

    * A new setting $DICT_TRUNCATE_FLAG has been added. If this is set to
      1, then bit 6 of the dictionary word flag is set for any word whose
      source code definition is truncated to fit in the dictionary. In
      --trace dict listings, this is shown as "tr" when the flag is set.
      Without this option, bit 6 of the dictionary word flag is set for
      all verbs (which is the old behavior, redundant with bit 0). If the
      compiler truncates only the //p flag (as in $LONG_DICT_FLAG_BUG),
      that does not count as truncating the dictionary word: the only
      relevant test is whether or not characters were dropped.

    * A new setting $GRAMMAR_VERSION has been added. Setting this has the
      same effect as the existing Grammar__Version constant, but provides
      a more standard way to set the grammar table version number.

    * An experimental new grammar version 3 can be enabled with the
      $GRAMMAR_VERSION setting (or the Grammar__Version constant). This
      is a variation on grammar version 2 with a more compact data
      structure, and is only available for Z-code. Note that using this
      grammar version will require library changes that are not currently
      in the Inform 6 library.

    * A new setting $GRAMMAR_META_FLAG has been added. If set to 1, there
      is a new way to declare meta actions. Previously, meta actions were
      defined by writing lines like
        Verb meta 'score' * -> Score;
      This associates the meta flag with the dictionary word "score".
      This is not ideal as we could have verbs which are meta in some
      phrasings but not others. If $GRAMMAR_META_FLAG is set the old
      syntax is still supported, but there is also a new syntax:
        Verb 'load'
          * noun -> Push
          * 'game' -> Restore meta;
      In this new approach, actions are sorted, with meta actions coming
      first. Game or library code can detect a meta action by comparing
      the action number with the new system constant
      #highest_meta_action_number, which is the highest meta action
      number after sorting all the actions.

    * It is now legal to have multiple Verb declarations for the same
      verb. This is now treated as if the subsequent declarations had
      been made with Extend, and a warning is produced to this effect.

    * The output of the --trace-verbs option now shows all verb synonyms,
      rather than just the first one.

    * It is now an error to declare two verbs that refer to the same
      dictionary word. Previously this was accepted, but generated an
      incorrect story file.

    * A new setting $ZCODE_COMPACT_GLOBALS has been added. If this is set
      to 1, then when compiling to Z-code, the compiler tracks how many
      global variables are used, and moves the start of arrays to
      immediately after that. If this is left as the default of 0, then
      the compiler always allocates 480 bytes in the story file's dynamic
      memory for globals.

    * A new setting $ZCODE_FILE_END_PADDING has been added. By default it
      is set to 1, but if it is set to 0, then when outputting a Z-code
      game file Inform 6 will no longer pad the file to be a multiple of
      512 bytes.

    * A warning is now issued if a dynamic string is used in another
      dynamic string or an abbreviation.

    * When compiling to Z-code version 3, the compiler now checks that
      the number of objects does not exceed the maximum possible, which
      is 255.

    * Various arithmetic opcodes are replaced with shorter versions:
        * @add x 0 -> x ! (skip)
        * @add x 0 -> y ! @store y x
        * @add x 1 -> x ! @inc x
        * @sub x 0 -> x ! (skip)
        * @sub x 0 -> y ! @store y x
        * @sub x 1 -> x ! @dec x
        * @mul x 1 -> x ! (skip)
        * @mul x 1 -> y ! @store y x
        * @div x 1 -> x ! (skip)
        * @div x 1 -> y ! @store y x

    * The property operator previously generated code like the following:
        @get_prop x p -> TEMP1
        @store y TEMP1
      This now skips the TEMP1 step and stores directly to the variable.

    * When performing Z-code branch optimizations, if there is a @jump to
      an @rtrue/@rfalse/@ret_popped, the @jump opcode is replaced with
      the return opcode, which shortens the jump by one byte. In some
      cases this leaves the original return opcode unreachable.
      Unfortunately the dead-code-strip phase has already finished by
      this point so it is not convenient to detect this and strip it out.

  Bugs fixed

    * Dictionary flags were being set incorrectly when $DICT_WORD_SIZE
      was set sufficiently large.

    * In --trace asm output, when a Z-string has abbreviation marks,
      <ABBR> is printed, rather than Ctrl-A characters.

    * With the $OMIT_SYMBOL_TABLE option enabled, the <action> section
      was missing from the "gameinfo.dbg" file.

    * Dictionary words in UTF-8 encoded source files are now printed
      correctly in --trace dict and -r (gametext.txt) output.

    * The compiler is now consistent in how it handles the redeclaration
      of a global variable in Z-code and in Glulx: this is allowed,
      provided that all declarations have the same initial value.

    * Dead code elimination no longer produces warnings on while loops
      where the closing brace cannot be reached, such as
        while (true) {
          i--;
          if (i > 0) continue;
          break;
        }


Compiler 6.42

   These are the changes delivered in version 6.42 of the Inform compiler.

  Features added

    * The compiler can now handle switch cases which are expressions,
      rather than just looking for bare literals and symbols. The
      expression must still evaluate to a constant, but now parentheses
      and constant-folded arithmetic are handled:
        Constant CONST = 5;

        ! These have always worked.
        switch (x) {
          0: return 0;
          1: return 1;
          -2: return -2;
        }

        ! These now also work.
        switch (x) {
          (0): return 0;
          (-(1)): return -1;
          (CONST): return 5;
          (CONST+1): return 6;
        }

      For backwards compatibility, the expression must be wrapped in
      parens, so -(1): is not a valid case. Lists of expressions are also
      supported. Expression parsing applies as long as the first value is
      wrapped in parens. Wrapping the entire list in parens also works:
        switch (x) {
          1, 2, 3: return 0;                   ! old style
          (4), (CONST), (CONST+1): return 1;   ! new style
          (10), CONST+6, CONST+7: return 2;    ! this also works
          (20, CONST+16, CONST+17): return 3;  ! as does this
        }

      Note that the to keyword does not support expressions. You cannot
      say (CONST) to (CONST+5): as a case. Also, case expressions only
      work within a switch statement. Top-level action cases must still
      be bare action names.

    * Inform identifiers can now be any length, and the entire identifier
      is significant. Dictionary words can also be any length. The
      DICT_WORD_SIZE limit still applies, but now dictionary words are
      silently trimmed to DICT_WORD_SIZE. For Glulx, DICT_WORD_SIZE can
      now be increased without limit.

    * Arbitrary bytes and words can be compiled into the game, using two
       new statements:
         @ -> BYTE BYTE BYTE ...;
         @ --> WORD WORD WORD ...;

      The given bytes or words are directly copied out into the function.
      (Words are two bytes in Z-code, and four bytes in Glulx.) The
      compiler assumes that the data forms valid opcodes, but does
      nothing to verify this. Bytes must be numeric constants, while
      words are either numeric constants or symbols, such as the name of
      a function.

    * A new setting exists to omit the symbol names table,
      $OMIT_SYMBOL_TABLE. The symbol names table contains the names of
      all properties, attributes, fake actions, and arrays as strings,
      and is generally only used by debug library code and debug veneer
      error messages. When $OMIT_SYMBOL_TABLE=1 is set:
        + The symbol names table is omitted from the game file, for both
          Glulx and Z-code.
        + The print (property) p statement will print <number 72> (etc.)
          instead of the property name.
        + The runtime error for a non-existent property (obj has no
          property prop to read) will similarly print a number instead
          of the property name.
        + The runtime error for array overflow (tried to read from -->5
          in the array "arr"...) will omit the array name.
        + The following system constants are not available, and trying
          to use one is a compile-time error: #identifiers_table,
          #attribute_names_array, #property_names_array,
          #action_names_array, #fake_action_names_array,
          #array_names_offset, #global_names_array,
          #routine_names_array, #constant_names_array.
      Note that the Inform 6 library uses #identifiers_table for some
      debugging verbs, and the Infix library extension uses all the
      affected constants. To update such code, the relevant logic that
      uses these symbol names and constants would be put in a #Ifndef
      OMIT_SYMBOL_TABLE; block.

    * A new setting $ZCODE_MAX_INLINE_STRING has been added to determine
      how long a string can be and still be compiled to a @print opcode,
      rather than be added to the string segment and compiled to a
      @print_paddr opcode. This setting has a default value of 32, which
      matches the previous behaviour of the compiler, where this limit
      was hard-coded at 32 characters.

    * The Abbreviate directive now accepts abbreviations of any length.

    * The -u option, which computes abbreviations, can now generate
      abbreviations of any length.

    * Inform is now able to correctly set the plural flag on long
      dictionary words (e.g. 'directions//p'). However, due to the way
      Inform 7 has defined plural kind names in the past, fixing this
      will affect the parsing of Inform 7 games if the output Inform 6
      code is then compiled with a version of Inform 6 that fixes this
      issue. As a result, there is a new setting $LONG_DICT_FLAG_BUG,
      which defaults to 1. The new behaviour is only enabled if this
      setting is set to 0.

    * Flags for dictionary words now include setting the NOUN flag, and
      also provides a way to explicitly not set a flag. The possible
      choices are:
        + //p sets the PLURAL flag (bit 2)
        + //n sets the NOUN flag (bit 7)
        + //~p means do not set the PLURAL flag at this point
        + //~n means do not set the NOUN flag at this point
      Dictionary words used in most contexts default to //n.

    * The --trace PROPS and --trace SYMDEF options now display the line
      number that each property or symbol is defined at.

    * The --trace ASM=2 option now shows backpatch markers as a short
      descriptive string, rather than as a number.

    * The statement print "^"; now compiles to a single opcode (@new_line
      for Z-code, or @streamchar 10 for Glulx) rather than printing a one
      character string.

    * For Glulx, with strict mode turned off, print (char) X; compiles to
      either @streamchar X or @streamunichar X, depending on whether X is
      a compile-time constant less than 256, or not.

    * Grammar table lines entries which have no verb are now omitted.
      When this occurs a warning is printed, as this most likely
      indicates an oversight in the game's source code.

    * Error messages about invalid tokens are now more informative.

    * Inform now handles line breaks itself, rather than relying on the C
      standard library. This gives consistent handling of Windows and
      Unix style line breaks on all platforms.

    * The output file "gametext.txt" now includes the Z-code or Glulx
      version being compiled to.

    * The Z-Machine opcodes added in revision 1.1 of the Z-Machine
      Specification Standard, set_true_colour and buffer_screen, are now
      supported.

  Bugs fixed

    * The Glulx random(x) built-in function now follows the DM4
      specification: if x is positive, the function returns the result of
      1+(@random x); if zero or negative, @setrandom x is called.

    * In several places (local variable declarations, action names and
      the Switches directive) the compiler would accept quoted strings
      and then ignore the quotes. This is now an error.

    * The case of a property having too many entries is now always an
      error, and is checked correctly in the case of compiling to Z-code
      V3.

    * An unclosed double quote at the end of a source file no longer
      causes the compiler to hang.

    * A number of issues relating to error messages giving incorrect
      information have been fixed by improving how the compiler handles
      backtracking through parsed symbols in some tricky cases.

    * The Z-code version of the veneer function Box__Routine (which is
      used in the implementation of the box statement) now contains a
      check to prevent calling the @set_cursor opcode with negative
      co-ordinates.

    * The veneer functions RA__Pr(), RL__Pr() and CP__Tab() are now
      correct for Z-code V3.

    * Errors in the declaration of arrays could sometimes cause the
      compiler to emit a large number of error messages, this is now
      fixed so that only the initial error is printed.

    * Invalid expressions like (a++ b), (a ~b), (a++ ~b), and (a++ --b)
      previously caused an internal compiler error, but now produce a
      sensible error message.

    * When computing abbreviations, the space character is now correctly
      treated as only occupying one byte, not four.

    * The argument supplied to the Z-machine opcode @jump is now
      interpreted correctly. Previously this was only done properly for
      the jump statement, not the opcode.


Compiler 6.41

   These are the changes delivered in version 6.41 of the Inform compiler.

  Features added

    * The dead code elimination logic now allows forward jumps to labels
      that would be otherwise unreachable, like this:
        if (condition) {
          jump MiddleLabel;
        }
        if (0) {
          while (condition) {
            ...
          .MiddleLabel;
            ...
          }
        }

    * The error that occurs when the compiler encounters a jump to an
      unknown label now includes the name of that label.


Compiler 6.40

   These are the changes delivered in version 6.40 of the Inform compiler.

  Features added

    * The various command line arguments that produce tracing or
      statistical information have been consolidated in a new argument:
      $!TRACEOPT or $!TRACEOPT=N. The Unix-style equivalent is --trace
      TRACEOPT or --trace TRACEOPT=N. You can also use $! by itself (or
      --helptrace) to list all available trace options. Trace option
      names are case-insensitive.
  
      The optional N is always an integer. 0 always means off, 1 is the
      base level, 2 or more may increase verbosity. As a general rule,
      setting N to a high number is not an error; it just does the same
      thing as the highest supported number for that option. (This lets
      us add more verbosity levels to any option without worrying about
      compatibility errors.)

      Four trace settings can be changed in mid-compile with the Trace
      directive. (This has always been true but now it is handled
      consistently.) Trace assembly, Trace expressions, Trace tokens and
      Trace linker are equivalent to --trace asm, --trace expr, --trace
      tokens and --trace linker, respectively. As with the command-line
      versions, you can optionally specify 0 to turn off that setting or
      2 or more for more verbosity.

      Four more trace directives do an immediate information dump: Trace
      dictionary, Trace objects, Trace symbols and Trace verbs. The
      command-line equivalents --trace dict, --trace objects, --trace
      symbols and --trace verbs do the same at the end of compilation.

      The following single-letter options have been removed and replaced
      with trace options:
        + -j: Replaced by --trace OBJECTS
        + -m: Replaced by --trace MEM
        + -n: Replaced by --trace PROPS (for property information) and
            --trace ACTIONS (for action numbers)
        + -p: Replaced by --trace MAP=2
        + -t: Replaced by --trace ASM=2
        + -y: Replaced by --trace LINKER
      The following single-letter options still exist, but are now
      aliases for trace options:
        + -a: Same as --trace ASM
        + -f: Same as --trace FREQ
        + -g: Same as --trace RUNTIME
        + -s: Same as --trace STATS
        + -z: Same as --trace MAP
      The following single-letter options have been removed entirely:
        + -b: Has not done anything since at least Inform 5.
        + -l: Was supposed to list all statements compiled, but it was
          never implemented.
        + -o: Showed the same information as -z or --trace MAP.
      The -l option did show include files being opened; this is now a
      separate trace setting, --trace FILES.
      Some of the information that used to be under -a4 is now a separate
      trace setting, --trace BPATCH.

    * The -u option now just outputs computed abbreviations. If you want
      the verbose calculation information that it used to print, use
      --trace FINDABBREVS or --trace FINDABBREVS=2.

    * The compiler is now capable of dead code elimination, allowing it to:
      + Discard unreachable opcodes and strings.
      + Minimize generated code for dead branches (if (0), if (1)).
      + Detect if and switch statements where every branch returns.
      + Detect loops that never exit (or always return).
      + Discard @jz constant opcodes where the constant is non-zero.
      + Convert @jz 0 to an unconditional @jump.
      + Discard a @jump to the very next instruction.
      + Discard store opcodes when computing a logical expression as a
        value, if one case (0 or 1) is impossible.
      + Fold expressions like (0 && expr) and (1 || expr), even when
        expr is not a constant.

    * When statements that can never be reached are eliminated, a warning
      is produced, where appropriate.

    * Dead code elimination does mean that theoretically possible (though
      very odd) valid code will now result in a compilation error. For
      example,
        if (DOSTUFF) {
          while (condition) {
            ...
          .MiddleLabel;
            ...
          }
        }
        jump MiddleLabel; ! error
      This will fail with a compilation error if DOSTUFF is defined as a
      constant zero. This optimization can be turned off by setting the
      compiler setting $STRIP_UNREACHABLE_LABELS to zero (its default is
      one).

    * There are now further warnings if the compiler detects that the
      type used in certain expressions is not correct:
      + X(), indirect(X): X must be a routine
      + X.Y, X.&Y, X.#Y: X must be a class or an object; Y must be a
        property (the Y checks already existed)
      + X.Y(): X must be a class, object, string or routine; Y must be
        a property
      + X.Y++, X.Y--, ++X.Y, --X.Y: X must be a class or an object; Y
        must be a property

    * There is a new syntax for dynamic-string interpolations: "@(N)".
      The original syntax was "@NN", which is still supported. In the new
      syntax "N" can be a number, or an already defined numeric constant.
      As a result of this, under Glulx the limit on $MAX_DYNAMIC_STRINGS
      being less than 100 has been removed.

    * The constants #dictionary_table and #grammar_table are now
       available when compiling to Z-code, as well as Glulx.

    * The command line switch to display percentages (-p) now works with
      Glulx, and acts as an extension to the -z switch.

    * The double precision floating point related opcodes added to the
      Glulx 3.1.3 specification (that is, @numtod, @dtonumz, @dtonumn,
      @ftod, @dtof, @dceil, @dfloor, @dadd, @dsub, @dmul, @ddiv, @dmodr,
      @dmodq, @dsqrt, @dexp, @dlog, @dpow, @dsin, @dcos, @dtan, @dasin,
      @dacos, @datan, @datan2, @jdeq, @jdne, @jdlt, @jdle, @jdgt, @jdge,
      @jdisnan, @jdisinf) are now supported. In addition there are also
      two new macros @dload and @dstore, to load and store double
      precision floating point values.

    * The undo related opcodes added to the Glulx 3.1.3 specification
      (that is, @hasundo and @discardundo) are now supported.

    * The Version and Switches directives are now deprecated, and produce
      a warning if used. The recommended way to set the Z-code version
      and any other switches is to use the command line, or !% comments
      at the top of the source file.

    * The ability to compile Inform source code as modules, and then
      later link it, has been removed. This functionality always had
      significant restrictions and was never widely used. The -M and -U
      command line options have been removed, along with the +module_path
      option. The Link and Import directives now just produce errors.

    * The ability to use temporary files for internal storage (the -F
      switch and the +temporary_path option) have been removed.

    * The = sign in the Global directive is now optional, just as it is
      in the Constant directive. So all of these are now legal:
        Constant c1 11;
        Constant c2 = 22;
        Global g1 33;
        Global g2 = 44;

    * The long deprecated forms of the Global directive that could define
      arrays have been removed. All these are now no longer legal:
        Global array --> size;
        Global array data ...;
        Global array initial ...;
        Global array initstr ...;

  Bugs fixed

    * Abbreviation directives now only add abbreviations to the output
      file if economy mode (-e) is set.

    * An array overrun when the $ZCODE_LESS_DICT_DATA setting is enabled
      has been fixed.

    * The logic that allows a test for the compiler version of the form
      #IfDef VN_1640 now requires what follows the "VN_" to be a number.


Compiler 6.36

  These are the changes delivered in version 6.36 of the Inform compiler.

  Features added

    * The algorithm used to apply abbreviations for Z-code has been
      replaced with a more efficient dynamic programming algorithm, based
      on the paper by R.A. Wagner "Common phrases and minimum-space text
      storage", Communications of the ACM, 16 (3) (1973).

    * Inform has been refactored to use dynamic memory allocation rather
      than fixed size buffers. As a result, the following settings are
      now removed: if the available space is filled, Inform will allocate
      more memory without requiring user intervention.
        + ALLOC_CHUNK_SIZE
        + SYMBOLS_CHUNK_SIZE
        + MAX_ABBREVS (removed only for Glulx)
        + MAX_ACTIONS
        + MAX_ADJECTIVES
        + MAX_ARRAYS
        + MAX_CLASSES
        + MAX_DICT_ENTRIES
        + MAX_EXPRESSION_NODES
        + MAX_GLOBAL_VARIABLES
        + MAX_INCLUSION_DEPTH
        + MAX_INDIV_PROP_TABLE_SIZE
        + MAX_LABELS
        + MAX_LINESPACE
        + MAX_LINK_DATA_SIZE
        + MAX_LOCAL_VARIABLES (now a constant)
        + MAX_LOW_STRINGS
        + MAX_NUM_STATIC_STRINGS
        + MAX_OBJ_PROP_COUNT
        + MAX_OBJ_PROP_TABLE_SIZE
        + MAX_OBJECTS
        + MAX_PROP_TABLE_SIZE
        + MAX_QTEXT_SIZE
        + MAX_SOURCE_FILES
        + MAX_STATIC_DATA
        + MAX_STATIC_STRINGS
        + MAX_SYMBOLS
        + MAX_TRANSCRIPT_SIZE
        + MAX_UNICODE_CHARS
        + MAX_VERBS
        + MAX_VERBSPACE
        + MAX_ZCODE_SIZE
        As a result of this, the memory size command line arguments
        ($SMALL, $LARGE and $HUGE) are now redundant, and have been
        removed.

    * It is now possible to declare an individual property with the
      Property directive:
         Property individual propname;

    * A new setting $ZCODE_LESS_DICT_DATA has been introduced. When set
      to a non-zero value, this tells the compiler to omit the last byte
      of Z-code dictionary entries (which can be referred as #dict_par3),
      as this is commonly unused.

    * There are now warnings if the compiler detects that the type used
      in certain expressions is not correct. This only checks expressions
      that contain defined symbols, and does not change the generated
      code. The checks are:
        + remove O: O is an object
        + move O to P: O is an object; P is an object or a class
        + give O A: O is an object; A is an attribute
        + O has/hasnt A: O is an object; A is an attribute
        + O in/notin P: O is an object; P is an object or a class
        + X ofclass C: C is a class
        + X provides P: P is a property
        + X.P, X.P(), X.&P, X.#P: P is a property

    * Assembly output (-a mode) now shows symbolic information for each
      assembly operand, if possible.

    * The -u switch now generates $MAX_ABBREVS possible abbreviations.

    * The Trace verbs directive now prints out the entire grammar table.

    * Using the -D switch when the game or library does not support
      debug_flag now produces an explanatory warning:
        DEBUG mode is on, but this story or library does not appear to support it

    * Expressions of the form (x <= y or z) or (x >= y or z) now produce
      a warning message: while their effect is documented, well defined,
      and is not being changed, it is not necessarily what a user might
      expect.

    * The check for whether an abbreviation actually reduces the size of
      the Z-code output file has been made more accurate, and the message
      if an abbreviation does not reduce the size is now a warning,
      rather than an error.

  Bugs fixed

     * For Glulx, stub functions (and the veneer function Symb__Tab()) are
       now always compiled as local-argument functions (with a type byte
       of 0xC1). Previously, they were in some cases compiled as
       stack-argument functions (with a type byte of 0xC0).

     * Counts of properties in errors and in the statistics report (output
       with the -s switch) are now consistent, and reflect how many
       properties the user can define.

     * The check that there are not too many common properties defined now
       correctly excludes individual and alias properties.

     * Inform will now report an error if the "class" line of a class
       definition mentions the class being defined.
     * A crash when compiling a malformed array declaration has been
       fixed.


Compiler 6.35

   These are the changes delivered in version 6.35 of the Inform compiler.

  Features added

     * Some Unix-style command line options are now supported, primarily
       to avoid the use of $ in command lines (although the old syntax is
       still supported). The new syntax for these options is:
  --help
  --path PATH=dir
  --addpath PATH=dir
  --list
  --size huge, --size large, --size small
  --helpopt SETTING
  --opt SETTING=number
  --config filename

     * Numeric constants can be declared as command line options, either
       like a setting:
  $#SYMBOL
  $#SYMBOL=NUM

       Or as a new Unix-style command line option:
  --define SYMBOL
  --define SYMBOL=NUM

       This defines SYMBOL as a constant, just like the Constant
       directive. Like that directive, if no value is supplied, it
       defaults to zero.
     * The settings $MAX_ABBREVS and MAX_DYNAMIC_STRINGS control the
       number of abbreviations and the number of dynamic strings,
       respectively. When compiling to Z-code these settings are linked,
       as they both use the same 96 Z-code abbreviations that are
       available.
     * The setting $TRANSCRIPT_FORMAT controls the output format of the -r
       option. The default is still the same format as before, (and can be
       explicitly selected with $TRANSCRIPT_FORMAT=0), but
       $TRANSCRIPT_FORMAT=1 enables the new, more informative and
       machine-readable format.
     * The Origsource directive, added in version 6.34, is now used in
       error reporting, regardless of the error format selected.
       (Previously it only appeared with the default error message format,
       E0.)
     * If an attempt is made to redefine an existing symbol, there is now
       a clearer error message, explaining what the error is and where the
       symbol was previously defined.
     * -g3 is now a valid option: it enables tracing for all routines,
       including the veneer. This functionality was added back in Inform
       6.21, but the code to check the actual option was omitted.
     * Using the option -k (which turns on the generation of debugging
       information) no longer implies -D (which turns on debug mode).

  Bugs fixed

     * Only the following directives are now allowed in a function or
       object definition: all others give an error:
  #ifv3
  #ifv5
  #ifdef
  #ifndef
  #iftrue
  #iffalse
  #ifnot
  #endif
  #message
  #origsource
  #trace

     * An #ifdef statement at the start of a switch block now compiles
       correctly, and no longer gives a spurious error.
     * The following, incorrect forms of array declaration now generate an
       error:
  Array foo --> 'dictword';
  Array foo --> FunctionName;
  Array foo --> [];

     * If a common property array overflows when compiling to Z-code
       version 3, the object is no longer corrupted.
     * The incorrect code
  Object foo with name 'x';

       now correctly causes the warning
  'name' property should only contain dictionary words

       when compiled to either Glulx or Z-code: previously the warning
       only appeared when compiling to Z-code.
     * The compiler now correctly handles #If directives around if and
       else clauses.
     * Forward declared properties (that is, properties that are used
       before they are defined in the game source code) now work
       correctly.
     * Where directives allow a constant to be used (Release, Version,
       Dictionary, Iftrue and Iffalse), the compiler now reports an error
       if the constant is not defined.
     * When compiling to Z-code version 3, dictionary words are now
       correctly truncated at 6 Z-characters (instead of 9).
     * When compiling to Z-code version 3, two dictionary words that
       differed only in Z-characters 7-9 would lead to two identical
       dictionary entries: now there will only be one entry.

Compiler 6.34

   These are the changes delivered in version 6.34 of the Inform compiler.

  Features added

     * The following system constants are now supported for Glulx:
       #highest_class_number, #highest_object_number,
       #lowest_attribute_number, #lowest_action_number,
       #lowest_routine_number, #lowest_array_number,
       #lowest_constant_number, #lowest_class_number,
       #lowest_object_number, and #lowest_property_number.
     * Unicode characters can now be included in Glulx word arrays as
       literals, e.g.
  Array text1 table "A @{1c4} A";
  Array text2 --> "A @oef A";

     * For Glulx, high-plane Unicode characters in the range $100000 to
       $10FFFF are supported in UTF-8 source code, and in @{...}
       sequences, which can now contain up to six hex digits.
     * The new command line switch -V simply prints the version and date
       of the compiler and then exits.
     * The new setting $SERIAL sets the six digit serial number written
       into the header of the game, e.g.
  $SERIAL=160305

     * It has always been possible to replace the paths used by the
       compiler with a command line option of the form +include_path=foo.
       It is now possible to add to an existing path without replacing it
       by using an additional '+' character, like so: ++include_path=foo.
     * The Replace directive can now be applied to routines in any file,
       whether it has the System_file directive or not. Replace also now
       works on recursive functions, which it previously did not. Its
       behavior can now be described this way:
  Replace Func;
  Replace Func OriginalFunc;

       Multiple definitions of Func() may follow this directive. Func will
       refer to the last-defined version, except that definitions in
       normal files are preferred over definitions in System_file files or
       the veneer. With the two-symbol form (introduced in 6.33), the
       latter symbol will refer to the first-defined version of the
       function.
     * A new Origsource directive has been added to allow a record of the
       location of the relevant in a higher-level language that has been
       converted to Inform 6. (In practice, this will very likely be the
       location in an Inform 7 source.) The syntax is
  Origsource <file>
  Origsource <file> <line>
  Origsource <file> <line> <char>
  Origsource

       The first three forms declare that all following lines are derived
       from the named Inform 7 source file (with an optional line number
       and character number). This will be reported in error messages and
       in debug output. The declaration holds through the next Origsource
       directive (but does not apply to included files). The fourth form,
       with no arguments, clears the declaration. Unlike the Include
       directive, Origsource does not open the named file or even verify
       that it exists. The filename is treated as an opaque string.
     * The constant $INDIV_PROP_START is now a setting that can be changed
       for Glulx.
     * Arrays that are never modified can be declared as "static": in
       Z-code, this places the array at the end of readable memory (after
       the dictionary and before the beginning of code storage); in Glulx,
       it places the array at the end of ROM (after string storage). The
       syntax is
  Array arrayname static --> 1 3 5 7 9 11 13 15;

  Bugs fixed

     * It is no longer possible to cause values to be pushed onto the
       stack but not then pulled by evaluating a logical expression but
       not assigning or using the result of that expression.
     * Replacing a recursive function now works correctly.
     * The output for the $list command line argument now includes the
       value of the $MAX_ARRAYS setting.
     * Memory settings can no longer overflow if set to very large values.
       These values are limited to a maximum of 999999999: setting them
       higher just results in a warning.
     * The debugging output file now contains the correct function
       addresses even when the compiler has been told to omit unused
       functions.
     * Invalid statements with empty parentheses (like return ();) now
       generate a sensible error.
     * Crashes caused by over-long identifiers have been fixed. Note that
       as a result, the previously allowed (although undocumented) use of
       strings or dictionary words in an action-based (implicit) switch
       statement now causes an error.
     * The object table is now always generated at an even Z-Machine
       address, as the logic in the veneer routine RA__Pr() requires this.
     * The F and u options are now explicitly disallowed with the Switches
       directive.
     * Assigning values to system functions now leads to an error message,
       rather than a crash.
     * Crashes due to over-long abbreviations have been fixed.
     * Representing the at symbol '@' by @{0040} now works when compiling
       to Glulx.
     * The USE_TEMPORARY_FILES option no longer has a bug that led to
       files being closed more than once.
     * The platform-specific definitions in header.h for Unix have been
       cleaned up: "UNIX64" has been removed, since it was identical to
       "UNIX"; and "UNIX" no longer implies "USE_TEMPORARY_FILES".
     * The platform-specific definitions in header.h for the Macintosh
       have been cleaned up: "MACINTOSH" is now "MAC_CLASSIC"; "OSX" is
       now "MACOS", and "MACOS" now uses "HUGE_SIZE" for the default array
       sizes.
     * The maximum length of a verb is now limited to 120 (which can be
       changed in the source code). Previously very long verbs would crash
       the compiler.
     * Compiling to Z-code version 3 has shown a number of regressions
       since Inform 6.15:
          + Diverted actions, of the form <<ACTION>>, are fixed.
          + The veneer routine RA__Pr() can be used.

Compiler 6.33

   These are the changes delivered in version 6.33 of the Inform compiler.

  Features added

     * Unused routines can now be detected and omitted from the compiled
       game, through two new settings. If $WARN_UNUSED_ROUTINES is set to
       1, unused routines (other than those in the Inform library) are
       reported during compilation; if it is set to 2, unused routines
       anywhere, even in the library, are reported. If
       $OMIT_UNUSED_ROUTINES is set to 1, unused routines are omitted.
     * A new command line switch -Cu can be used to specify that the
       source file character set is UTF-8, allowing source files to
       contain Unicode characters beyond those defined in ISO 8859-1 to
       8859-9.
     * A new #Undef directive will cause a previously defined constant to
       become undefined.
     * #Ifdef directives are now allowed within an object declaration.
     * Action statements can have an optional extra ‘actor’ argument,
       allowing action statements of the form
  <Take pie, orc>; ! simple form
  <<Look, floyd>>; ! auto-returning form

       Note that this also requires a library change to be useful.
     * A previously declared routine can be renamed with a new form of the
       Replace directive. For example, if a source file contained
  Replace Banner OriginalBanner;

       It could then (after including the library) contain this definion
       of a function:
  [ Banner;
    OriginalBanner();
    print "Extra version info!^";
  ];

       The library's banner code would then be in OriginalBanner().
     * The previously deprecated Dictionary directive can now have the
       following forms:
  Dictionary 'word';
  Dictionary 'word' val1;
  Dictionary 'word' val1 val3;

       The first of these forms just adds the word to the dictionary, with
       all flags set to zero, if it is not already in the dictionary. The
       second form also sets the dict_par1 flag to the given value, or
       bitwise-or’s the value in if the word already exists. The third
       form also sets the dict_par3 in the same way as for dict_par1.
       The values can be numeric literals or constants. They can be 0-255
       for Z-code, or 0-65535 for Glulx.
     * The “font on” and “font off” statements now call the @set_font
       opcode for Z-code V5 and higher.
     * The Glulx version of the Unsigned__Compare() veneer routine has
       been changed to a more efficient implementation, using Glulx’s
       unsigned comparison opcodes.
     * The debugging output file, generated when the -k is used, has been
       changed to a new, XML-based format.
     * Two new Z-code settings have been added to support the extra words
       in the header extension table specified in section 11.1.7 of the
       Z-Machine Standards Document version 1.1. $ZCODE_HEADER_EXT_WORDS
       specifies how many extra words to add (so for all three words
       defined in the 1.1 standard, this would be set to 3).
       $ZCODE_HEADER_FLAGS_3 specifies the value to put in the first of
       these three words, which is the "flags3" field.
     * A new Glulx setting $GLULX_OBJECT_EXT_BYTES has been added, which
       specifies an amount of additional space to add to each object
       record. The default is 0.

  Bugs fixed

     * Function calls of the form f(g)(h) (that is, where f() returns the
       address of a function that is called with h as its argument) are
       now compiled correctly: previously, such calls were compiled as if
       the code was f(g(h)).
     * The bounds checking related to internal arrays that are are sized
       from various compiler settings has been improved, so that it should
       not be possible to crash the compiler if these settings are too
       small. In addition, a start has been made on allowing the compiler
       to grow its internal buffers, rather than relying on these settings
       to specify sufficient buffer sizes.
     * The error message shown when too many global variables are declared
       now tells the user to increase the $MAX_GLOBAL_VARIABLES setting.
     * The setting $MAX_CLASS_TABLE_SIZE, which was not used anywhere, has
       been removed.
     * The compiler no longer crashes if run with the -k switch and passed
       a source file containing no routines at all.
     * Floating-point constants in “#Ifdef TARGET_GLULX;” sections do not
       now cause an error when compiling to Z-code.
     * The error message produced if an action routine is not found for an
       action name has been improved to include the action name, and a
       sensible line number.
     * The compiler is now better at not producing spurious additional
       errors after it has encountered a directive that contains an error.
     * The compiler no longer crashes when reporting errors after line
       65,535 in long Inform 6 source files.
     * The compiler now reports a meaningful text compression rate when
       outputting statistics for Glulx with the -Gs switches.
     * An error is now reported if a source file ends with an unterminated
       object definition.
     * The three argument form of the read statement no longer assumes
       that the routine passed as the third argument to the statement will
       not change the global variable that the statement uses internally.
     * The 'Abbreviate' statement now works with words containing
       non-English characters.
     * Attempting to use @pop opcode for V5 or higher no longer results in
       a crash.
     * The Glulx setting $NUM_ATTR_BYTES, which determines the number of
       bytes in an object set aside for attribute flags, now works
       correctly. Note that this has required a change to the veneer
       routines that conflicts with the definition of FUNC_2_CP__Tab() in
       the ‘Accelerated Functions’ section of the Glulx 3.1.2
       specification. If you change this setting, you should take great
       care if you also use the Glulx accelerated functions feature (as
       Inform 7 does by default).
     * The syntax of declaring a function so that it prints its name and
       arguments:
  [ Whatever * x y;
    ! Whatever function logic ...
  ];

       is now supported for Glulx.
     * The statistics produced by the -s compiler switch are now correct
       for Glulx.

Compiler 6.32

   These are the changes delivered in version 6.32 of the Inform compiler.

  Features added

   Items of the form [C63NNN] quote the feature’s reference number in the
   ‘Compiler’ section of the Inform Patch List.
     * The Z-machine opcodes for pushing and pulling values from the stack
       are @push and @pull, used like this:
  @push x;
  @pull x;

       However for Glulx the opcode syntax is different: instead the @copy
       opcode is used:
  @copy x sp;
  @copy sp x;

       The compiler now supports the @push and @pull syntax under Glulx as
       an alias for @copy, allowing the same code to be used for both the
       Z-machine and Glulx. [C63104]
     * Custom Glulx opcodes (such as opcodes that post-date the compiler)
       can now be specified with the custom opcode syntax. The format of
       this syntax is
  @"FlagsCount:Code"

       Flags (which are optional) can include “S” for store, “SS” for two
       stores, “B” for branch format, or “R” if execution never continues
       after the opcode. Count is the number of arguments (currently
       limited to 0-9), and Code is a decimal integer representing the
       opcode number.
       For example, @"S3:123" is the syntax for a three-argument opcode
       (load, load, store) whose opcode number in decimal is 123, and
       @"2:234" is the syntax for a two-argument opcode (load, load) whose
       number is 234. [C63107]
     * When compiling to Glulx, the Glulx format version number of the
       resulting story file is usually determined by which Glulx opcodes
       are used in the source code. This version number can now be
       over-ridden by providing a -v command line argument after the -G
       switch to select Glulx mode. For example, the arguments -G -v3.1.0
       set the Glulx version number to “3.1.0”. [C63108]
     * The Unicode related opcode added to the Glulx 3.0.0 specification,
       @streamunichar, is now supported.
     * When compiling to Glulx, characters outside of the ISO 8859-1 range
       can now be used in strings. The maximum number of such characters
       allowed is determined by a new memory setting, $MAX_UNICODE_CHARS.
     * When compiling to Glulx, the syntax
  print (char) value;
       now works for values greater than 255, printing the appropriate
       Unicode character. (For such values @streamunichar is used; for
       those less than or equal to 255, @streamchar is used as before.)
     * The memory heap related opcodes added to the Glulx 3.1.0
       specification (that is, @mzero, @mcopy, @malloc and @mfree) are now
       supported.
     * The acceleration related opcodes added to the Glulx 3.1.1
       specification (that is, @accelfunc and @accelparam) are now
       supported. There is also a new syntax to get the address of a
       global variable var, with the expression “#g$var”: this is provided
       so that such addresses can be provided to the @accelparam opcode.
     * The floating point related opcodes added to the Glulx 3.1.2
       specification (that is, @numtof, @ftonumz, @ftonumn, @ceil, @floor,
       @fadd, @fsub, @fmul, @fdiv, @fmod, @sqrt, @exp, @log, @pow, @sin,
       @cos, @tan, @asin, @acos, @atan, @atan2, @jfeq, @jfne, @jflt,
       @jfle, @jfgt, @jfge, @jisnan and @jisinf) are now supported.
     * Floating point constants can be used in the Inform source code.
       Thes constants are expressed in the form “$+1.0e+1”: that is, a
       dollar sign, followed by a plus or minus sign, followed by a
       floating point number, and then optionally a positive or negative
       integer exponent. Inform does not attempt anything other than
       converting these constants to their 32-bit integer representation:
       there is no constant folding as there is with integers, so the
       expression “$+1.0 + $+1.0” is not meaningful, and does not produce
       the floating point value “2.0”.
       As an example of the use of these constants, the following adds
       together 100 and 123.45:
  @fadd $+100 $+1.2345e+2 result;
       The compiler also defines the constants “FLOAT_INFINITY”,
       “FLOAT_NINFINITY” and “FLOAT_NAN” for positive infinity, negative
       infinity and “not a number”, respectively.
     * Glulx has a simple memory extension feature, where the game’s
       header declares the memory space to be larger than the game file.
       The extra space is filled out with zeroes when the game starts.
       This is now supported by a new option $MEMORY_MAP_EXTENSION. This
       defaults to 0: if it is redefined to a larger value then the size
       of the game’s memory space is extended by that amount.
     * The number of verbs allowed by the compiler when compiling to Glulx
       is no longer limited to fewer than 256. As part of producing the
       game file, the compiler creates a dictionary table that contains
       verb numbers. However, despite in Glulx there being space for a
       verb number between 0 and 65535 in this table, only one byte of it
       (that is, values between 0 and 255) was used. This has been fixed.
       However, this also requires library changes to be useful, as the
       library makes use of this dictionary table. The library used by
       Inform 7 has been adjusted to take advantage of this, but the
       Inform 6/11 library has not.
     * The dictionary of Glulx games can now contain characters outside of
       ISO 8859-1. There is a new memory setting, $DICT_CHAR_SIZE: by
       default this is 1, but setting it to 4 causes the compiler to
       create a dictionary containing 32-bit Unicode characters.
       However, this also requires library changes to be useful, as the
       library makes use of this dictionary table.

  Bugs fixed

   Items of the form [C63NNN] quote the bug’s reference number in the
   ‘Compiler’ section of the Inform Patch List.
     * Strict mode is no longer enabled by default when generating V3 and
       V4 Z-code files, as strict mode makes use of opcodes that are V5+
       only. [C63007]
     * The base unit of Inform’s internal memory allocation for various
       structures (for example the buffer used to hold the generated code)
       is no longer fixed: it is now controlled by a setting
       $ALLOC_CHUNK_SIZE. This allows, for example, the maximum Glulx code
       size to be greater than 640Kb. [C63102]
     * When compiling to Glulx, the stack size of the resulting story file
       is no longer fixed at 4096: it can be changed by the setting
       $MAX_STACK_SIZE. [C63108]
     * The compiler could crash if the size of the grammar table exceeded
       the size of the Z-machine readable memory: this is now fixed.
       [C63110]
     * Creating a Z-code game file with precisely 64Kb of readable memory
       produced an invalid file. This is now prevented, so that the
       largest readable memory size is 64Kb minus 2 bytes. [C63112]
     * Previously, under Glulx the print_to_array() function could be
       called with either two arguments, specifying both the array to
       print to and its length, or just one argument, the later matching
       what is allowed when compiling to Z-code. This one argument form
       has now been withdrawn under Glulx as a security hole, and a source
       to problems with writing beyond the end of the array: now the array
       length must be specified. (See also Features available only in
       Glulx.)
     * Veneer routines are no longer excluded from Inform’s assembly
       output (which is accessed with the -a command line switch).
     * For Linux and other Unix variants the default memory settings have
       been increased, which should remove the need to change the compiler
       settings when building large projects on these platforms.
     * For Mac OS X, the maximum length of a file path is now 8192
       characters, which should prevent any further problems with long
       paths on this platform.

Compiler 6.31

   These are the changes delivered in version 6.31 of the Inform compiler.

  Bugs fixed

   Items of the form [C63NNN] quote the bug’s reference number in the
   ‘Compiler’ section of the Inform Patch List.
     * When individual properties are read (successfully), there is no
       longer a futile attempt to look up the property index in the common
       property table. [C63016]
     * Complex if statements, of the form if (x == 1 or 3 or 5 ... or 99),
       now don’t crash the compiler. [C63013]
     * The compiler is better at handling lengthy path names. [C63009]
     * Backpatching and other strange errors no longer occur if the code
       size of a V8 game exceeds 256K. [C63005]
     * An Object or Class definition with more than 32 common property
       values now doesn’t cause an internal compiler error. [C63001]

Compiler 6.30

   These are the changes delivered in version 6.30 of the Inform compiler.

  Features added

     * The compiler automatically defines a WORDSIZE constant, whose value
       is 2 when compiling for the Z-machine, and 4 when the target is
       Glulx. The constant specifies the number of bytes in a VM word, and
       we recommend that you use it in the small number of circumstances
       where this value is significant. The compiler also defines a
       constant TARGET_GLULX if you supply the -G switch, or TARGET_ZCODE
       otherwise; in both cases the constant value is 0. For more
       information on the use of these constants, see Support for Glulx.
     * The Switches directive, which enables certain compiler switches to
       be set from within the source file rather than on the compiler
       command line, has been superseded by a more powerful mechanism. The
       special comment characters “!%”, occurring on the very first line
       or lines of the source file, enable you to specify Inform Command
       Language (ICL) commands to control the compilation. For example:
  !% -E1G                                    ! Glulx, 'Microsoft' errors
  !% -~S                                     ! disable Strict mode
  !% +include_path=./test,./,../lib/contrib  ! look in 'test' library
  !% $MAX_STATIC_MEMORY=20000
  Constant STORY "RUINS";
  ...

       ICL is described in §39 of the Inform Designer’s Manual. In brief:
       each line specifies a single command, starting with “-” to define
       one or more switches, “+” to define a path variable, or “$” to
       define a memory setting. Comments are introduced by “$”. The ICL
       command “compile” is not permitted at the head of a source file.
     * Two new ICL memory settings are available; both of these could
       previously be changed only by rebuilding the compiler.
       $MAX_SOURCE_FILES has a default of 256, and $MAX_INCLUSION_DEPTH
       has a default value of 5.
     * A new directive, similar to Array ... string and Array ... table,
       is provided:
  Array array buffer N;
  Array array buffer expr1 expr2 ... exprN;
  Array array buffer "string";

       This creates a hybrid array of the form used by
       string.print_to_array() and the new library routine
       PrintToBuffer(), in which the first word array-->0 contains N and
       the following N bytes array->WORDSIZE, array->(WORDSIZE+1) ...
       array->(WORDSIZE+N-1) contain the specified expression values or
       string characters.
     * A new (A) print rule — similar to the existing (The) — prints an
       object’s indirect article with its first letter capitalised. The
       printed article is “A” or “An” by default, or else taken from the
       object’s article property.
     * The minimum size of the Z-code header extension table can be set
       using the command line switch -Wn. For example, -W6 makes the table
       at least six words long.
     * Source code in character sets other than ISO 8859-1 to 8859-9 is
       now supported, provided that the character set can be mapped onto
       one of the ISO 8859 sets.
       A mapping file is used to define how the source code is to be
       processed. This file consists of a directive indicating the ISO
       8859 set to be mapped to, followed by 256 numbers giving the
       mapping. As an example, under Microsoft Windows, Russian text is
       encoded with the character set defined as Microsoft code page 1251.
       The following text defines a mapping to the ISO 8859-5 set:
  ! Windows Cyrillic (code page 1251) to ISO 8859-5
  C5
    0, 63, 63, 63, 63, 63, 63, 63, 63, 32, 10, 63, 10, 10, 63, 63
   63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63
   32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47
   48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63
   64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79
   80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95
   96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111
  112,113,114,115,116,117,118,119,120,121,122,123,124,125,126, 63
  162,163, 44,243, 34, 46, 63, 63, 63, 63,169, 60,170,172,171,175
  242, 39, 39, 34, 34, 46, 45, 45,152, 84,249, 62,250,252,251,255
   32,174,254,168, 36, 63,124,253,161, 67,164, 60, 63, 45, 82,167
   63, 63,166,246, 63, 63, 63, 46,241,240,244, 62,248,165,245,247
  176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191
  192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207
  208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223
  224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239

       Lines starting with “!” are treated as comments. The next line,
       beginning with “C”, defines the ISO set to map to in the same way
       as the -Cn command line switch.
       To use the mapping, Inform treats each character in the source file
       as a number between 0 and 255, and uses that number as an index
       into the mapping table. For example, suppose that the character
       read in from a Russian Windows text file is the Cyrillic small
       letter “ya”.This character is represented in the Russian Windows
       character set by the number 255. Inform takes the 255th entry in
       the mapping, which is 239. Therefore the character is regarded as
       being 239 in ISO 8859-5.
       The name of the mapping file is specified by a new compiler path
       variable +charset_map. If the above mapping is held in a text file
       win1251.map, a Russian game could be compiled with a command line
       of the form:
  inform +charset_map=win1251.map +language_name=Russian mygame.inf

     * The @check_unicode and @print_unicode opcodes, introduced in the
       Z-Machine Standards Document version 1.0, can now be called by name
       rather than by using the clumsier generic syntax @"EXT:11S" and
       @"EXT:12S". For example:
  @print_unicode $0401; ! Cyrillic capital letter IO

     * Strict mode (which compiles run-time integrity checks into your
       game) has been decoupled from Debug mode (which defines debugging
       verbs like TRACE and SHOWOBJ). This means that it’s no longer
       necessary to turn off Strict checking (in order to disable the
       Debug verbs) before releasing a game, though of course you can do
       so if you wish to save space and increase performance. By default,
       Strict mode is enabled (turn it off with -~S) and Debug mode is
       disabled (turn it on with -D).
     * The compiler now issues a warning if you use array->n on an array
       of words, or array-->n on an array of bytes. Use the new Array ...
       buffer directive to create a hybrid array which can be accessed
       without these warnings.
     * The compiler also issues a warning if you refer to an unqualified
       property name within a routine, for example by typing (number==0)
       when you intended (self.number==0).
     * Another new warning appears if you include something other than a
       dictionary word in an object’s name property. This is most commonly
       triggered if you try to add a single-letter word by typing name 'g'
       'string' when you intended name 'g//' 'string'.

  Bugs fixed

   Items of the form [C62NNN] quote the bug’s reference number in the
   ‘Compiler’ section of the Inform Patch List.
     * A problem with multiple assignment involving pointer arithmetic in
       Strict mode giving the wrong answer has been fixed. [C62127]
     * After using Extend only to separate off an element of an existing
       Verb definition, new synonyms for the separated verb now work
       correctly; previously they were applied to the residue of the
       original definition. [C62126]
     * Strict mode now tests for the use of @put_prop or @get_prop opcodes
       when a common property is longer than two bytes — the Z-Machine
       Standards Document says that this is illegal, and that the result
       is unspecified. The error message is of the form “[** Programming
       error: obj (object number N) has a property prop, but it is longer
       than 2 bytes so you cannot use "." to read **]”. This means that
       you have used the obj.prop construct in the situation where prop is
       a common property containing two or more values; typically prop is
       being explicitly used as an array, or it’s an additive property and
       both obj and its parent class have defined values for it. The
       problem does not occur if prop is an individual property. [C62125]
     * Handling of European quotes is (finally) correct: the “«” symbol is
       produced by any of @<<, @@163 and @{00AB}, while any of @>>, @@162
       and @{00BB} produce the matching “»”. Note, however, that this
       problem originated in an error in the previous version of the
       Z-Machine Standards Document, and therefore older interpreters
       written to that specification, or more recent ones adjusted to work
       with the incorrect fix introduced at Inform 6.12, may still not
       give the correct results. [C62124]
     * The “no such constant” compilation error message now quotes the
       number of the appropriate source line. [C62123]
     * The metaclass() and ZRoutine() routines no longer report large
       unsigned values — above the game’s Static memory area — as of type
       String. More usefully, the constant NULL (-1) is not reported as a
       String. [C62122]
     * Complex expressions combining a routine call and the ofclass and or
       operators no longer generate incorrect code. [C62121]
     * Negative constants in assembly operations — for example,
       @set_colour 4 (-1); — no longer cause the compiler to report an
       unexpected expression. [C62119]
     * Various problems with handling ISO 8859 characters in the range
       128-255, and also in the use of @@ escape sequences, have been
       resolved. [C62117, C62115, C6211, C62003]
     * An Abbreviate directive containing a substring of “<unknown
       attribute>” may crash the compiler; hopefully, no more. [C62116]
     * The 320Kb size limit placed by Inform on v6 and v7 games has been
       raised to 512Kb. [C62114]
     * Following a Zcharacter directive replacing the entire alphabet
       table, dictionary entries are no longer corrupted. [C62113]
     * The compiler now generates conditional branches spanning up to 63
       bytes, lifting the previous unnecessary limit of a 31-byte span and
       leading to slightly shorter code. [C62112]
     * Putting an object in itself doesn’t now loop indefinitely. [C62110]
     * Various problems with the @store, @inc_chk, @dec_chk, @not and @je
       opcodes have been resolved. [C62109, C62108, C62105]
     * Problems with nested conditional compilation directives
       #Ifndef...#Ifnot...#Endif have been resolved. [C62107]
     * A long dictionary word — such as 'elephants//p' — now correctly
       sets the plural bit. [C62103]
     * Problems with constant folding — that is, having the expression
       evaluated at compile-time — partly addressed in the previous
       bi-platform compiler, have been fixed. [C62102]
     * When compiling for Glulx, the compiler uses the @callf, @callfi,
       @callfii or @callfiii opcodes where applicable for generated calls
       instead of always pushing arguments onto the stack and using @call.
     * The presence of a Switches G; directive no longer causes the
       compiler to crash.
     * An unexpected limit of 1024 labels per routine in the Z-machine
       assembly language generated by the compiler has been raised to
       32768. The most likely way to encounter this limit is by creating a
       switch statement with an extremely large number of cases.
     * A problem with the read statement generating the wrong opcode in a
       version 4 game has been corrected.
     * A dynamic class declaration such as Class Pebble(NUM_PEBBLES) ... ;
       no longer creates a mysteriously large number of instances if
       NUM_PEBBLES isn’t defined.

Library 6/11

   These are the changes delivered in version 6/11 of the Inform library.

  Features added

     * The library automatically defines four constants: LIBRARY_PARSER at
       the end of Parser.h, LIBRARY_VERBLIB at the end of VerbLib.h,
       LIBRARY_GRAMMAR at the end of Grammar.h, and LIBRARY_ENGLISH at the
       end of English.h. Contributed library extensions can use these
       constants to check that they have been Included in the correct
       location. A fifth constant LIBRARY_VERSION, currently defined as
       the number 611, can be checked by extensions which require this
       particular version of the library.
     * The word “wall” has been removed from the CompassDirection objects
       defined in English.h, whose names are now simply “north”, “south”,
       etc.
     * The verbs LOOK [TO THE] NORTH, LOOK DOWN, LOOK OUT[SIDE] etc — but
       not LOOK IN[SIDE], which is already available — have been added. By
       default, the response is of the form “You see nothing unexpected
       ...”, but you can change this for individual directions in
       individual rooms by providing a compass_look property:
  Room   study "Your study"
    with description "There is a doorway to the east of this austere room.",
         compass_look [ obj;
             if (obj == e_obj) "You see a doorway.";
             if (obj == n_obj or s_obj or w_obj) "You see the wall.";
         ],
         e_to hallway;

       This enhancement uses the mechanism described in this topic in the
       Inform 6 FAQ (except that the compass_look property was previously
       named compasslook), and means that you no longer need to make the
       library changes described there.
     * The verbs ASK npc TO command and TELL npc TO command — both
       synomymous with npc,command — are provided. The new grammar is:
  Verb 'ask'
      ...
      * creature 'to' topic -> AskTo
      ...

       in which the creature token matches the npc and the topic token
       represents the command. AskTo isn’t an action in the usual sense:
       it’s trapped by the parser and converted to the original
       npc,command format. The npc can intercept the command by providing
       an orders property in the usual way — see §18 of the Inform
       Designer’s Manual.
       This enhancement means that you may no longer require Irene
       Callaci’s AskTellOrder.h library extension.
     * The verbs RECORDING [ON|OFF] and REPLAY are now always available,
       irrespective of the DEBUG state. This may cause compilation errors
       if you have already defined these verbs yourself.
     * The verbs PRY, PRISE, PRIZE and LEVER have been added. This may
       cause compilation errors if you have already defined these verbs
       yourself.
     * The parser treats input lines beginning with “*” as a comment,
       without attempting any further parsing. The character used to
       introduce comments can be changed by defining COMMENT_CHARACTER
       before you Include Parser. For example:
  Constant COMMENT_CHARACTER '!';
       Since comments are used primarily when capturing a transcript —
       either of a complete game (SCRIPT ON) or of input commands only
       (RECORDING ON) — the parser responds “[Comment recorded]” or
       “[Comment NOT recorded]” as appropriate.
     * The selfobj object now includes an empty add_to_scope property,
       which you can over-ride with your own routine, typically to equip
       the player with body parts. For a single object:
  selfobj.add_to_scope = nose;
       or for multiple objects:
  [ IncludeBodyParts; PlaceInScope(nose); PlaceInScope(hands); ];
  selfobj.add_to_scope = IncludeBodyParts;

     * The task-based scoring system (§22 of the Inform Designer’s Manual)
       uses a byte array, which precludes the awarding of large or
       negative scores. To get round this, you can Replace the TaskScore()
       library routine as follows, and then define task_scores as a word
       array:
  Replace TaskScore;
  Array task_scores --> 100 200 300 400 (-50) 600;
  [ TaskScore i; return task_scores-->i; ];

     * The scoring system is completely disabled if you define a constant
       NO_SCORE near the start of your game.
  Constant NO_SCORE;
     * A new before_implicit property is available; at the moment this is
       used only by the parser, when it is about to perform an implicit
       TAKE (for example, EAT APPLE when you’re not holding the apple).
       You can give this property to an object if you wish to control the
       parser’s behaviour. The property’s value should be a constant or a
       routine which returns: 0 to report “(first taking the...)” and then
       attempt to do so (this is what currently happens); 1 to attempt the
       TAKE without first issuing the message, 2 to proceed with the
       requested action without attempting the TAKE, or 3 to object that
       “You aren’t holding that!”. The object can test action_to_be to
       determine which action has triggered the TAKE:
  before_implicit [;
    Take: if (action_to_be == ##Eat) return 2;
  ],

     * A new system variable sys_statusline_flag is set to 1 initially if
       you have used the statusline time; directive in your program to
       show a clock, and to 0 otherwise. It can be changed by the program.
     * An object’s invent property — if it has one — is now invoked both
       when displaying the player’s inventory and when including the
       object in a room description. invent is invoked in the usual way
       (with inventory_stage first set to 1, and then set to 2) both when
       mentioning the object in a room description, and when listing it in
       the player’s inventory. By default you’ll get the same output each
       time. If you need to distinguish between the two occasions, you can
       test (c_style&PARTINV_BIT) — true during a room description — or
       (c_style&FULLINV_BIT) — true during an inventory. Here’s an
       example:
  Object  -> "sack"
    with  name 'sack',
          invent [;
              ! When listing objects in the player's inventory
              if (c_style&FULLINV_BIT) rfalse;

              ! When listing objects at the end of a room description
              if (inventory_stage == 1) switch (children(self)) {
                  0: print "an empty sack";
                  1: print "a sack containing ", (a) child(self);
                  default: print "an assortment of objects in a sack";
                  }
              rtrue;
              ],
    has   container open;

       This enhancement uses the mechanism described in this topic in the
       Inform 6 FAQ and means that you no longer need to Include
       WriteList.
     * The turns counter is now initialised to 0, not 1. You can change
       this if you define a constant START_MOVE near the start of your
       game.
  Constant START_MOVE 1;
     * A new LibraryExtensions object is defined, whose function is to act
       as a parent to initialisation objects created by library
       extensions. These objects may provide ext_initialise and/or
       ext_messages property routines, whose role is to help integrate the
       extension into a game. This is best explained by example.
       Consider the SmartCantGo.h extension, which replaces “You can’t go
       that way” messages by the more informative “You can go only north,
       south and east”, and can be integrated into a game by adding a
       ChangeDefault(cant_go, SmartCantGo) statement to your Initialise()
       routine. Instead of requiring the author to make this addition, the
       extension could now cause it to happen automatically by defining an
       initialisation object as a child of LibraryExtensions, like this:
  Object  "(SmartCantGo)" LibraryExtensions
    with  ext_initialise [; ChangeDefault(cant_go, SmartCantGo); ];

       Just before calling the game’s Initialise() routine, the library
       loops through the children — if any — of LibraryExtensions, and
       executes those ext_initialise properties that it finds there. The
       property routines can perform any appropriate setup processing that
       would otherwise have to be inserted into the Initialise() routine
       itself; for example, starting a daemon running.
       A similar process takes place when displaying library messages. The
       library first checks whether the author has provided a
       LibraryMessages object to intercept the message which it is about
       to display. If not, it now loops through the children of
       LibraryExtensions, and executes ext_messages properties that it
       finds there. If none of those routines returns true to signal that
       the message has been dealt with, the standard library text is then
       printed in the usual way. For example, here’s how an extension
       might automatically intercept Inventory messages (unless the game
       has already handled them via LibraryMessages):
  Object  "(someInventoryExtension)" LibraryExtensions
    with  ext_messages [;
              Inv: switch(lm_n) {
                1: "You are empty-handed.";
                2: "Your possessions include";
              }
          ];

       Note that this is an experimental feature, and may be modified or
       extended in the light of experience.

  Library routines

   Several new library routines are provided to harmonise
   commonly-encountered differences between the Z-machine and Glulx VMs
   (see also Library routines available only in Glulx).

   KeyCharPrimitive()

     waits for a single key, and returns the character from 1-255 (or,
     for Glulx, one of the Glk special key codes.). For Glulx only, an
     extended form is available — see Library routines available only in
     Glulx.

   KeyDelay(time)

     waits time tenths of a second for a single key. If no key is pressed
     within that period it returns zero; otherwise it returns the
     character from 1-255.

   ClearScreen()
   ClearScreen(selector)

     ClearScreen() clears both the status line and the main window. The
     cursor moves to the top of the screen. The routine should be
     followed by a call to MoveCursor() or MainWindow(). Alternatively,
     using ClearScreen(selector): if selector is 0, both are cleared; if
     selector is 1 only the status line is cleared; if selector is 2 only
     the main window is cleared.

   MoveCursor()
   MoveCursor(line, column)

     MoveCursor() selects the status line for output. MoveCursor(line,
     column) selects the status line for output and moves the cursor to
     the given line and column within the status area, where line 1 is
     the top line and column 1 is the far left. (This is necessary
     because the Glk convention is to number both lines and columns from
     0 rather than 1.)

   MainWindow()

     selects the main (buffered) text window for output.

   StatusLineHeight(lines)

     sets the height of the status line in lines. The standard
     DrawStatusLine() calls this every turn, which isn’t a bad thing,
     since StatusLineHeight() is smart. If you replace DrawStatusLine(),
     maintain this convention. (The library menu routines fiddle with the
     status line, and it’s up to DrawStatusLine() to reset it after the
     menus are over.)

     A new library variable gg_statuswin_cursize holds the current
     setting (in both VMs).

   ScreenWidth()

     returns the number of characters that can be printed in a monospaced
     font between the left and right borders of the currently selected
     window. For Glulx only, the extended form ScreenWidth(win) works on
     a specified window id; note that the results are unreliable if the
     normal style for that window uses a proportional font.

   ScreenHeight()

     returns the height in lines of the main window.

   SetColour(fg, bg)
   SetColour(fg, bg, selector)

     SetColour(fg, bg) sets the current foreground and background text
     colours, using the same codes as the @set_colour opcode in the
     Z-machine (1=default, 2=black, 3=red, 4=green etc.). Using
     SetColour(fg, bg, selector), colours can be set separately in each
     window: if selector is 0, both are set (the top window will have
     inverted colours for the Z-machine); if selector is 1 only the
     status line is affected; if selector is 2 only the main window is
     affected.

     All colour functions are effective only if the library variable
     clr_on is set to non-zero.

     The advantage over @set_colour is that when the player restores a
     saved game or types UNDO, the colours will be correct for that state
     of the game.

     For Glulx, the routine produces an appropriate effect if style hints
     are enabled by the interpreter; it also clears the screen. For the
     Z-machine, a separate call to ClearScreen() is required.

     These associated constants are now provided for use with
     SetColour(); the final three are useful also with ClearScreen():
  Constant CLR_DEFAULT 1;
  Constant CLR_BLACK 2;
  Constant CLR_RED 3;
  Constant CLR_GREEN 4;
  Constant CLR_YELLOW 5;
  Constant CLR_BLUE 6;
  Constant CLR_MAGENTA 7;
  Constant CLR_CYAN 8;
  Constant CLR_WHITE 9;
  Constant CLR_PURPLE 7;
  Constant CLR_AZURE 8;
  Constant WIN_ALL 0;
  Constant WIN_STATUS 1;
  Constant WIN_MAIN 2;

   DecimalNumber(num)

     prints num as a decimal number (it is in fact identical to print
     num;). It may be useful in conjunction with...

   PrintToBuffer(array, arraylen, string)
   PrintToBuffer(array, arraylen, obj)
   PrintToBuffer(array, arraylen, obj, prop)
   PrintToBuffer(array, arraylen, routine, arg1, arg2)

     prints its arguments — a string, an object’s name, the value of an
     object’s property, or a routine with up to two arguments — to the
     buffer array. The number of characters written to the buffer is a
     word at array-->0 (and is the value returned by the routine); the
     actual characters start at array->WORDSIZE. The maximum number of
     characters is specified in arraylen; for the Z-machine, an overrun
     caused by printing more than this value will produce an error
     message that you have corrupted the contents of memory beyond the
     array (for Glulx, the output is automatically truncated at the
     specified arraylen).

     For Glulx, see also PrintAnyToArray() in Library routines available
     only in Glulx, which has slightly extended capabilities, and which
     returns the number of characters written rather than writing them at
     array-->0.

   Length(string)
   Length(obj, prop)

     returns the number of characters in the string. Note that this
     prints to one of the parser arrays, and therefore it is your
     responsibility to ensure that the length cannot be greater that 160
     characters.

   UpperCase(char)
   LowerCase(char)

     return char in upper or lower case (if it was alphabetic), or
     unchanged (otherwise). Changes affecting A-Z and a-z are always
     reliable; changes to accented characters will not work if you have
     supplied a compiler switch -C2 through -C9, or used a Zcharacter
     directive to adjust the standard ZSCII character set.

   PrintCapitalised(obj, prop, flag, nocaps)

     is based upon PrintOrRun(obj, prop, flag). PrintOrRun() tests
     obj.prop, and either runs it (if a Routine), or prints it (if a
     String). In the latter case, a newline is then output unless flag is
     true. PrintCapitalised() does all that; the difference is that the
     first letter of any output is in upper case unless nocaps is true.

   Cap(string, nocaps)

     prints the string with the first letter in upper case, unless nocaps
     is true. Can also be used as a print rule:
  print ..., (Cap) myString, ...;

   Centre(string)
   Centre(obj, prop)

     prints a single-line string approximately centrally between the left
     and right borders of the screen by preceding it with an appropriate
     number of spaces. The routine works only for monospaced fonts (that
     is, after font off;), and is only likely to work well in the main
     Glulx window if the normal style for TextBuffer uses a
     non-proportional font. It is however useful for centring information
     in the status line. Can also be used as a print rule:
  print ..., (Centre) myString, ...;

   PrintOrRunVal(value, flag)

     if value refers to to an object, prints that object’s name; if value
     refers to a routine, runs that routine; if value refers to a string,
     prints that string (with a terminating newline unless flag is true).

  Bugs fixed

   Items of the form [L610NN] quote the bug’s reference number in the
   ‘Library’ section of the Inform Patch List.
     * A command like EMPTY ME no longer replies “yourself can't contain
       things”. [L61036]
     * The commands TAKE ALL FROM X and REMOVE ALL FROM X, where X is a
       closed or empty container, now produce sensible messages rather
       than “You can’t see any such thing” and “You can’t use multiple
       objects with that verb” respectively. [L61035]
     * A problem with the misbehaviour of name properties on rooms, in
       conjunction with THE, has been corrected. [L61034]
     * The command PUT X INTO X now correctly produces “You can’t put
       something inside itself”, rather than “You can’t see any such
       thing”. [L61033]
     * Run-time errors resulting from IndirectlyContains() attempting to
       find the parent of a Class which supports dynamic creation of
       objects have been resolved. [L61032]
     * Code in Parser__parse() which deals with looking ahead to the
       indirect object in cases like PUT ALL INTO BAG (a MULTIEXCEPT
       token) and TAKE ALL FROM BAG (a MULTIINSIDE token) now correctly
       sets the advance_warning global (to BAG). [L61031, L61023]
     * The Inform Designer’s Manual (p. 98) states that SHOWOBJ should
       accept an object number; now it does. [L61030]
     * The YesOrNo() routine now re-prompts correctly after garbage input.
       [L61029]
     * The parse buffer is no longer declared and initialised incorrectly
       (albeit harmlessly). [L61028, L60708]
     * The Inform Designer’s Manual (p. 93) defines the calling order of
       routines and properties for the ‘Before’ stage as follows:
         1. GamePreRoutine()
         2. orders of the player
         3. react_before of every object in scope
         4. before of the current room
         5. before of the first noun, if specified
       In the library, however, steps 3 and 4 are executed in reverse
       order. They are now as documented. [L61027]
     * A found_in floating object which the player is able to take
       (probably due to a coding error) is no longer silently dropped when
       the player returns to one of the listed rooms. [L61026]
     * A small problem with inherited describe properties has been
       corrected. [L61025]
     * Standard screen-handling is now implemented in v6 games. [L61022]
     * The handling of “You can’t go that way” messages is made
       consistent. Also, the statement ChangeDefault(cant_go,myRoutine);
       now works. [L61020]
     * Attempting to place an object in/on an object where it is already
       now results in “It’s already there”, rather than “You need to be
       holding it before you can put it into something else”. [L61019]
     * A problem with misleading inventory listing has been clarified.
       [L61018]
     * The command LEAVE X now correctly produces “But you aren’t in/on
       the X”, if appropriate. [L61017]
     * The response to READ was inappropriate when an object is misspelled
       or out of scope. [L61016]
     * A small bug in the choice of library messages for PUSH and TURN,
       which wasn’t noticeable unless you overrode the messages to be
       different from PULL, has been corrected. [L61015]
     * If you are in a dark room, you cannot examine what you are holding.
       Yet if you open a container you brought in from a lit room, the
       standard message “You open the box, revealing a...” was not being
       suppressed. [L61014]
     * The ScoreMatchL() routine in Parserm.h incorrectly decided which
       objects meet descriptors. As a result, some objects that didn’t
       meet descriptors were not properly removed from the match list when
       the library is deciding which objects best match a player’s input.
       [L61013]
     * The Infix problem parsing commands containing commas and periods
       has been fixed. [L61010]
     * A problem when describing what’s visible after opening a container
       has been corrected. [L61009]
     * An inappropriate message after GO NORTH CIRCULAR has been
       corrected. [L61008]
     * Modified foreground and background colours are now correct after
       RESTORE and UNDO. [L61007]
     * The grammar property now works with a large game whose dictionary
       lies above $8000. [L61006]
     * A buffer conflict with disambiguation and UNDO has been resolved.
       [L61004]
     * If a player is inside a closed, non-transparent container, the
       library prints an extra blank line between the header “The
       container” and the first inside_description line it prints. No
       more. [L61002]
     * The list writing routines do not handle plural containers
       correctly. If you have two empty boxes, it might list “two boxes
       (which is closed)”. Not only should it say “are closed”, but it
       will lump empty containers together even if some are open and
       others aren’t. Now resolved. [L61001]
     * A conflict between DrawStatusLine() and DisplayStatus() on how to
       determine whether to display turns or time is settled in favour of
       checking a header flag. [L60709]

Support for Glulx

   One of the limitations of the Z-machine is the size of the largest game
   that it supports: 256Kb if you compile a version 5 game, or 512Kb if
   you compile for version 8. If you find yourself up against this limit
   and you’ve tried all the standard tricks to save a few bytes here and
   there, then it’s time to switch to Glulx. That’s easy to do: you just
   supply the -G compiler switch, the compiler generates Glulx code, and
   any Glulx interpreter will be able to run it.

   Actually, it isn’t always quite that simple...

  Knowing which is which

   As mentioned earlier, the compiler automatically defines a couple of
   useful constants. If you’re compiling for the Z-machine then
   TARGET_ZCODE is defined; if you’re compiling for Glulx then you’re
   given TARGET_GLULX instead. You can use these with the Ifdef directive,
   like this:
  #Ifdef TARGET_ZCODE;
  ! Z-machine code here
  #Endif;
  #Ifdef TARGET_GLULX;
  ! Equivalent Glulx code here
  #Endif;

   or more commonly like this:
  #Ifdef TARGET_ZCODE;
  ! Z-machine code here
  #Ifnot;
  ! Equivalent Glulx code here
  #Endif;

   You’ll find a lot of this if you look in the library files, but it’s
   less frequently needed in a source file.

  Glulx differences

   The two VMs are not identical, and you need to be aware of their
   differences.

    Word size

   The most basic difference between Glulx and the Z-machine is that words
   are four bytes long instead of two. All Glulx variables are 32-bit
   values, the stack contains 32-bit values, property entries are 32-bit
   values, and so on.

   In most Inform programming, you don’t need to worry about this change
   at all. For example, if you have an array
  Array mylist --> 10;

   ...then Z-code Inform allocates ten words — that is, twenty bytes — and
   you can access these values as mylist-->0 through mylist-->9. If you
   compile the same code under Glulx Inform, the compiler again allocates
   ten words — now forty bytes — and you can still access them as
   mylist-->0 through mylist-->9. Everything works the same, except that
   the array can contain values greater than the Z-machine’s limit of
   65535.

   Table arrays also refer to two- or four-byte word values, and the first
   word is the length of the array. String and -> arrays, and the ->
   notation, still refer to single bytes. You should not have to modify
   your code here, either.

   There are two important cases where you will have to modify your code.
   First is the .# operator. The expression obj.#prop returns the length
   of the property in bytes. Since properties almost always contain words
   rather than bytes, it is very common to have Z-machine code like:
  len = (obj.#prop) / 2;
  for (i=0 : i<len : i++)
      print (string) (obj.&prop)-->i;

   In Glulx Inform programs, it is necessary to divide by 4 instead of by
   2, so you should replace the above code with:
  len = (obj.#prop) / WORDSIZE;
  for (i=0 : i<len : i++)
   print (string) (obj.&prop)-->i;

   This will compile and run correctly in both VMs.

   The other circumstance where your code may need modifying in this
   manner is when using the ‘print to array’ feature. Code like this:
  Array mybuf buffer 100; ! must be big enough for largest string you'll print
  mystr = "hello";
  mystr.print_to_array(mybuf);

   results in the first word of mybuf containing 5 (the number of
   characters in mystr), and the following five bytes containing ‘h’, ‘e’,
   ‘l’, ‘l’ and ‘o’. In the Z-machine, you could then output the
   characters from the array with either of these code fragments:
  len = 2 + mybuf-->0
  for (i=2 : i<len : i++)
   print (char) mybuf->i;

  len = mybuf-->0
  for (i=0 : i<len : i++)
   print (char) mybuf->(i+2);

   Again, you can make the code safe for both VMs if you change “2” to
   “WORDSIZE”:
  len = WORDSIZE + mybuf-->0
  for (i=WORDSIZE : i<len : i++)
   print (char) mybuf->i;

  len = mybuf-->0
  for (i=0 : i<len : i++)
   print (char) mybuf->(i+WORDSIZE);

   See also Features available only in Glulx for details of print_to_array
   under Glulx.

    Directives

   Glulx handles the majority of Inform directives, with two exceptions:
     * The Zcharacter directive causes a compilation error, since Glulx
       does not use the ZSCII character set. Your best approach is to
       bypass the directive when compiling for Glulx:
  #Ifdef TARGET_ZCODE;
  Zcharacter ... ;
  #Endif;

     * The (obsolete) Lowstring directive causes a run-time error when
       used like this:
  Lowstring mystr "hello";

  string 0 mystr;
  print "@00 and goodbye.";

       This simpler form, avoiding the use of Lowstring, works
       successfully:
  string 0 "hello";
  print "@00 and goodbye.";

       See also Features available only in Glulx for additional printing
       variable support.

    Statements

   Glulx handles the majority of Inform statements, with a few exceptions.
   If you try to use any of these statements in Glulx, you will cause a
   compilation error:
     * save, restore: These are more complicated procedures in Glulx than
       in Z-code, and cannot be implemented without involving library
       variables and routines. If you want to do this sort of thing,
       modify or copy the library SaveSub() and RestoreSub() routines.
     * read: Similarly, reading a line of text in Glulx involves the
       library; the compiler cannot generate stand-alone code to do it.
       See instead the library KeyboardPrimitive() routine.
     * @opcode: The Z-machine assembly language is completely different
       from that of Glulx. If you have used any assembly instructions, you
       will need to conceal them when compiling for Glulx, as described in
       Knowing which is which. See also Features available only in Glulx
       for details of the glk() function call.

   Glulx now supports the Inform style statement, mapping the Z-machine
   forms onto Glk styles:

     Inform statement Equivalent Glk style
     style roman;     style_Normal
     style reverse;   style_Alert
     style bold;      style_Subheader
     style underline; style_Emphasized
     style fixed;     style_Preformatted

   However, it is important to remember that, with Glulx, the appearance
   of a game is under the player’s control — Glulx interpreters enable the
   font parameters associated with each style to be specified at run-time.
   Therefore, you should use styles with caution, and if necessary alert
   the player to the settings which your game expects.

    Character handling

   Unlike the Z-machine, which internally uses the ZSCII character set
   (see the Inform Designer’s Manual Table 2 on p. 519), Glulx uses
   strings consisting of either 8-bit characters in the ISO 8859-1
   (Latin-1) encoding (which is the same as ZSCII for character values
   0-127, but different for character values 128-255), or 32-bit Unicode
   characters. In general you don't need to worry about which string
   representation is used: the compiler will figure it out for you. The
   impact is as follows:
     * @escape_sequence: Escape sequences such as @:a and @LL (for “ä” and
       “£” respectively) are accepted identically by both VMs.
     * @@decnum: The number is the character’s internal decimal value, so
       @@65 is “A” in both VMs, but @@165 is “ï” in the Z-machine and “¥”
       in Glulx.
     * @{hexnum}: The number is the character’s Unicode value, so @{41} is
       “A” and @{EF} is “ï” in both VMs. However, @{A5} is “¥” in Glulx,
       but causes a Z-machine compilation error because “¥” isn’t a ZSCII
       character.
     * -Cn: The compiler switches -C1 through -C9 specify that the source
       file uses the character set defined by ISO 8859-1 through 8859-9
       respectively. In the Z-machine, the switch also initialises the
       higher ZSCII character set to appropriate values; this later
       feature is irrelevant when compiling for Glulx.
     * Dictionaries in Glulx Inform 6 games have to consist of only ISO
       8859-1 characters at present. This is being worked on, and the
       necessary compiler changes have been made, but further library work
       is still needed.

    Compiler switches

   We’ve already mentioned the -G command line switch, which causes the
   compiler to output code for Glulx rather than for the Z-machine. There
   are a few other changes in this area (see the Inform Designer’s Manual
   Table 3 on p. 521).

     Switch To     Meaning
     -k     off/on incompatible with -G (output debugging information)
     -v*    3 to 8 incompatible with -G (set Z-machine Version)
     -G     off/on compile for Glulx VM
     -H     off/on use Huffman compression on Glulx strings (on by default)
     -X     off/on incompatible with -G (include Infix debugger)

  Glulx additions

   Glulx offers some additional capabilities above those of the Z-machine:

    Features available only in Glulx

     * For Glulx, print_to_array function requires two arguments, the
       first being the array to print to, and the second the length of
       that array:
  len = mystr.print_to_array(mybuf, 80);
       This example writes no more than 76 characters into the array. If
       mybuf is an 80-byte array, you can be sure it will not be overrun.
       (Do not try this with the second argument less than 4.)
       The value written into mybuf-->0, and the value returned, are not
       limited to the number of characters written; they represent the
       number of characters in the complete string. This means that:
  len = mystr.print_to_array(mybuf, 4);
       is an ugly but perfectly legal way to find the length of a string.
       (And in this case, mybuf need only be four bytes long.)
     * Z-code Inform supports 32 printing variables, @00 to @31, which you
       can include in strings and then set with the statement:
  string num "value";
       In Glulx, this limit is raised to 64. Furthermore, in Glulx you can
       set these variables to a stand-alone routine as well as a string:
  [ routine; print "value"; ];

  string num routine;

       In this case, the routine is called with no arguments and the
       result discarded; you should print your desired output inside the
       routine.
       In Glulx, unlike Z-code, a printing variable string can itself
       contain @.. codes, allowing recursion. You can nest this as deeply
       as you want. However, it is obviously a bad idea to cause an
       infinite recursion. For example, this will certainly crash the
       interpreter:
  string 3 "This is a @03!";
  print "What is @03?";

     * Many of the things that used to be Z-code assembly are now handled
       by Glk function calls. Making a Glk function call from Inform is
       slightly awkward, but not difficult.
       All of Glk is handled by the built-in Inform function glk(), which
       takes one or more arguments. The first argument is an integer; this
       tells which Glk call in being invoked. The remaining arguments are
       just the arguments to the Glk call, in order.
       Say, for example, that you want to set the text style to
       “preformatted”. The Inform code to accomplish this is:
  glk($0086, 2);
       The hex value $0086 means glk_set_style; the value “2” means
       Preformatted.
       The table of Glk calls, and the integers that refer to them, is
       given in Section 12.1.6 of the Glk specification (remember that the
       values given there are hexadecimal).
       Since calls based on numeric codes are not very easy to read, we
       recommend that you download John Cater’s infglk.h library header,
       which defines wrapper functions and constants. For example, you
       could achieve the same effect with this call:
  glk_set_style(style_Preformatted);
       When you read the Glk specification, bear in mind that the NULL
       value it talks about is the C language NULL (0), not the Inform
       Library NULL (-1). infglk.h defines a constant GLK_NULL (equal to
       0) which you can use where appropriate.
     * By default, arguments to routines work the same in Glulx as they do
       in Z-code. When you call a routine, the arguments that you pass are
       written into the routine’s local variables, in order. If you pass
       too many arguments, the extras are discarded; too few, and the
       unused local variables are filled with zeroes.
       However, the Glulx VM supports a second style of routine. You can
       define a routine of this type by naming the first argument
       _vararg_count. For example:
  [ StackFunc _vararg_count ix pos len;
      !   Glulx code here
  ];

       If you do this, the routine arguments are not written into the
       local variables. Instead, they are pushed onto the stack, and you
       must use Glulx assembly to pull them off. All the local variables
       are initialized to zero, except for _vararg_count, which (as you
       might expect) contains the number of arguments that were passed in.
       Note that _vararg_count is a normal local variable, aside from its
       useful initial value. You can assign to it, increment or decrement
       it, use it in expressions, and so on.
       Stack-argument routines are most useful if you want a routine with
       variable arguments, or if you want to write a wrapper that passes
       its arguments on to another routine.

    Library routines available only in Glulx

   KeyCharPrimitive(win, nostat);

     If win is nonzero, the character input request goes to that Glk
     window (instead of gg_mainwin, the default.) If nostat is nonzero,
     any window rearrangement event is returned immediately as value
     80000000 (instead of the default behavior, which is to call
     DrawStatusLine() and keep waiting.)

   PrintAnything(thingie, ...);

     In the Z-machine, strings and routines are “packed” addresses,
     dictionary words are normal addresses, and game objects are
     represented as sequential numbers from 1 to #top_object. These
     ranges overlap; a string, a dictionary word, and an object could
     conceivably all be represented by the same numeric value.

     In Glulx, all those things are represented by normal addresses, so
     different items will always have different values. Furthermore, the
     first byte found at the address is an identifier value, which
     specifies what kind of item the address contains.

     PrintAnything() prints any thingie — string, routine (with optional
     arguments), object, object property (with optional arguments), or
     dictionary word — known to the library.

     Calling                           Is equivalent to
     PrintAnything()                   (nothing printed)
     PrintAnything(0)                  (nothing printed)
     PrintAnything(string)             print (string) "string";
     PrintAnything(dictionaryword)     print (address) 'dictionaryword';
     PrintAnything(obj)                print (name) obj;
     PrintAnything(obj, prop)          obj.prop();
     PrintAnything(obj, prop, args...) obj.prop(args...);
     PrintAnything(routine)            routine();
     PrintAnything(routine, args...)   routine(args...);

     Extra arguments after a string or dictionary word are safely
     ignored. The (first) argument you pass in is always interpreted as a
     thingie reference, not as an integer. This is why none of the forms
     shown above print out an integer. However, you can get the same
     effect by calling
  PrintAnything(DecimalNumber, num);

     ...which is where the DecimalNumber() routine comes in handy. You
     can also, of course, use other library routines, and do tricks like
  PrintAnything(EnglishNumber, num);
  PrintAnything(DefArt, obj);

     None of this may seem very useful; after all, there are already ways
     to print all those things. But PrintAnything() is vital in
     implementing the following routine:

   PrintAnyToArray(array, arraylen, thingie, ...);

     This works the same way, except that instead of printing to the
     screen, the output is diverted to the given array.

     The first two arguments must be the array address and its maximum
     length. Up to that many characters will be written into the array;
     any extras will be silently discarded. This means that you do not
     have to worry about array overruns.

     The PrintAnyToArray() routine returns the number of characters
     generated. (This may be greater than the length of the array. It
     represents the entire text that was output, not the limited number
     written into the array.)

     It is safe to nest PrintAnyToArray() calls. That is, you can call
     PrintAnyToArray(routine), where routine() itself calls
     PrintAnyToArray(). (However, if they try to write to the same array,
     chaos will ensue.)

     It is legal for arraylen to be zero (in which case array is ignored,
     and may be zero as well.) This discards all of the output, and
     simply returns the number of characters generated. You can use this
     to find the length of anything — even a function call.

    Entry points available only in Glulx

   An entry point is a routine which you can provide in your code, or
   leave out; the library will call it if it’s present, ignore it if not —
   see §21 of the Inform Designer’s Manual.

   The library has some entry points which aid in writing more complicated
   interfaces — games with sound, graphics, extra windows, and other fancy
   Glk tricks. If you’re just writing a standard Infocom-style game, you
   can ignore this section.

   HandleGlkEvent(ev, context, abortres)

     This entry point is called every time a Glk event occurs. The event
     could indicate nearly anything: a line of input from the player, a
     window resize or redraw event, a clock tick, a mouse click, or so
     on.

     The library handles all the events necessary for a normal
     Infocom-style game. You need to supply a HandleGlkEvent() routine
     only if you want to add extra functionality. The ev argument is a
     four-word array which describes the event. ev-->0 is the type of the
     event; ev-->1 is the window involved (if relevant); and ev-->2 and
     ev-->3 are extra information. The context argument is 0 if the event
     occurred during line input (normal commands, YesOrNo(), or some
     other use of the KeyboardPrimitive() library routine); 1 indicates
     that the event occurred during character input (any use of the
     KeyCharPrimitive() library routine). The abortres argument is used
     only if you want to cancel player input and force a particular
     result; see below.

     If you return 2 from HandleGlkEvent(), player input will immediately
     be aborted. Some additional code is also required:
     * If this was character input (context==1), you must call the Glk
       cancel_char_event function, and then set abortres-->0 to the
       character you want returned. Then return 2; KeyCharPrimitive() will
       end and return the character, as if the player had hit it.
     * If this was line input (context==0), you must call the Glk
       cancel_line_event function. (You can pass an array argument to see
       what the player had typed so far.) Then, fill in the length of the
       input to be returned in abortres-->0. If this is nonzero, write the
       input characters sequentially into the array starting at
       abortres-->WORDSIZE, up to (but not including)
       abortres-->(WORDSIZE+len). Do not exceed 256 characters. Then
       return 2; KeyboardPrimitive() will end and return the line.

     If you return -1 from HandleGlkEvent(), player input will continue
     even after a keystroke (for character input) or after the enter key
     (for line input). You must re-request input by calling
     request_char_input or request_line_input. Any other return value
     from HandleGlkEvent() (a normal return, rfalse, or rtrue) will not
     affect the course of player input.

   InitGlkWindow(winrock)

     This entry point is called by the library when it sets up the
     standard windows: the story window, the status window, and (if you
     use quote boxes) the quote box window. The story and status windows
     are created when the game starts (before Initialise()). The quote
     window is created and destroyed as necessary.

     InitGlkWindow() is called in five phases:
    1. The library calls InitGlkWindow(0). This occurs at the very
       beginning of execution, even before Initialise(). You can set up
       any situation you want. (However, remember that the story and
       status windows might already exist — for example, if the player has
       just typed RESTART.) This is a good time to set gg_statuswin_size
       to a value other than 1. Return 0 to proceed with the standard
       library window setup, or 1 if you’ve created all the windows
       yourself.
    2. The library calls InitGlkWindow(GG_MAINWIN_ROCK), before creating
       the story window. This is a good time to set up style hints for the
       story window. Return 0 to let the library create the window; return
       1 if you have yourself created a window and stored it in
       gg_mainwin.
    3. The library calls InitGlkWindow(GG_STATUSWIN_ROCK), before creating
       the status window. Again, return 0 to let the library do it; return
       1 if you have created a window and stored it in gg_statuswin.
    4. The library calls InitGlkWindow(1). This is the end of window
       setup; you can take this opportunity to open other windows. (Or you
       can do that in your Initialise() routine. It doesn’t matter much.)
    5. The library calls InitGlkWindow(GG_QUOTEWIN_ROCK), before creating
       the quote box window. This does not occur during game
       initialization; the quote box window is created during the game,
       whenever you print a quote, and destroyed one turn later. As usual,
       return 1 to indicate that you’ve created a window in gg_quotewin.
       (The desired number of lines for the window can be found in
       gg_arguments-->0.)

     However you handle window initialization, remember that the library
     requires a gg_mainwin. If you don’t create one, and don’t allow the
     library to do so, the game will shut down. Contrariwise, the status
     window and quote windows are optional; the library can get along
     without them.

   IdentifyGlkObject(phase, type, ref, rock)

     This entry point is called by the library to let you know what Glk
     objects exist. You must supply this routine if you create any
     windows, filerefs, file streams, or sound channels beyond the
     standard library ones. (This is necessary because after a RESTORE,
     RESTART, or UNDO command, your global variables containing Glk
     objects will be wrong.)

     IdentifyGlkObject() is called in three phases:
    1. The library calls IdentifyGlkObject() with phase==0. You should set
       all your Glk object references to zero.
    2. The library calls IdentifyGlkObject() with phase==1. This occurs
       once for each window, stream, and fileref that the library doesn’t
       recognize. (The library handles the two standard windows, and the
       files and streams that have to do with saving, transcripts, and
       command records. You only have to deal with objects that you
       create.) You should set whatever reference is appropriate to the
       object. For each object: type will be 0, 1, 2 for windows, streams,
       filerefs respectively; ref will be the object reference; and rock
       will be the object’s rock, by which you can recognize it.
    3. The library calls IdentifyGlkObject() with phase==2. This occurs
       once, after all the other calls, and gives you a chance to
       recognize objects that aren’t windows, streams, or filerefs. If you
       don’t create any such objects, you can ignore that bit. But you
       should also take the opportunity to update all your Glk objects to
       the game state that was just started or restored. (For example,
       redraw graphics, or set the right background sounds playing.)

  Information for translators

   The library is designed to be easily translatable, and there are
   currently versions available in French, German and several other
   languages. If you maintain one of these translations, the following
   information may be useful to you.

    English.h

   This is the “language definition file”, and in translation is replaced
   by French.h, German.h, etc. The following changes have been made:
     * Class CompassDirection and its objects have been extensively
       revised.
     * Routine LanguageVerb() has been reworked.
     * Routines LanguageVerbIsDebugging(), LanguageVerbLikesAdverb() and
       LanguageVerbMayBeName() have been added to isolate
       language-specific tests previously embedded in parserm.h.
     * Constants YOU__TX and COMMA__TX have been added.
     * Routine LanguageLM() has been sorted alphabetically.
     * In that routine, CommandsOff, CommandsOn and CommandsRead have been
       added.
     * Also in that routine, Exit, Inv, Look, Miscellany, Places, Pronouns
       and Score have been extended, and Go has been modified.
     * Constant LIBRARY_ENGLISH has been added. We suggest that translated
       versions instead define LIBRARY_DUTCH, LIBRARY_FRENCH,
       LIBRARY_GERMAN, LIBRARY_ITALIAN, LIBRARY_SPANISH, LIBRARY_SWEDISH
       etc, in case it becomes useful at some time to determine which
       language is in force.

    Grammar.h

   This file contains grammars for English verbs like TAKE and DROP, and
   in translation is replaced by FrenchG.h, GermanG.h, etc. The following
   changes have been made:
     * The grammars have been sorted alphabetically.
     * Verb definitions 'recording' and 'replay' are no longer conditional
       on DEBUG.
     * Verb definitions 'showobj', 'ask', 'exit', 'look' and 'tell' have
       been extended.
     * Verb definition 'pry' 'prise' etc has been added.
     * Constant LIBRARY_GRAMMAR has been added.
