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.
A problem with dynamic memory reallocation used for buffers in the compiler, which could lead to spurious errors when compiling with Inform 6.43.
A case where the line number in a "no such constant" error message was wrong.
With $ZCODE_COMPACT_GLOBALS turned on, references in functions to arrays before the array declaration were backpatched to an incorrect address.
Output showing the Z-machine memory map gave an incorrect size for the global variables area with $ZCODE_COMPACT_GLOBALS enabled.
The optimization logic could read outside allocated memory if it encountered an undefined label.
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.
A 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:
The property operator previously generated code like the following:
@get_prop x p -> TEMP1 @store y TEMP1This 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.
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;
}
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:
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:
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.
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.
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.
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:
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:
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:
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 ...;
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.