Inform Release Notes

# Inform 6.4 Release Notes

## 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 Nelson for permitting it in the first place, and to Andrew Plotkin, who is responsible for most of the actual changes to the compiler code.

## Inform 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.

## Inform 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.