Inform 6.42

A new release of Inform 6, version 6.42, is now available from the Inform 6 Github project, and from the IF-Archive: Release notes, source code and Windows console executable.

Credit for virtually all of these changes goes to Andrew Plotkin.

Inform 6.42 was released on 10th February 2024.

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.



Woot woot!


As a reminder, the overview of I6 features that postdate the DM4 can be found at Inform 6 Reference Addendum.