The standard hierarchy of inter code generated by Inform.


§1. Status. The line between what is part of the Inter specification, and what is simply a convention about its use, is a fine one. For example, Inter allows arbitrary sets of primitives and of annotations, but in practice the Inform toolchain standardises both: see Inform Primitives and Inform Annotations.

Similarly, the Inter specification allows great flexibility in how packages are used to structure a program, but the Inform toolchain has definite ideas about that — as follows.

§2. Global area and main. As in every Inter program, the global area (outside of all packages) simply defines packages and pragmas. At present, Inform generates pragmas only for Inform 6 memory settings: even those are now probably not needed, and may go. All of the actual program is in the /main package, which has type _plain.

/main contains the standard subpackages /main/architecture and /main/connectors, both of which have type _linkage. The first defines architectural constants such as WORDSIZE, while the second is used to manage the import and export of symbols while linking trees together, and cannot contain content other than symbols. Neither really contains the program as such.

§3. Compilation modules. The only other content of /main is its set of "modules". Each one is a subpackage of type _module. They originate as follows:

In a sense the completion and synoptic modules play a similar role to each other, and a long-term aspiration might be to move more of the former into the latter, with a view to full linking of code some day. (At present the tool-chain can precompile — "assimilate" — kits and link them in, but not extensions written in Inform 7 source text.) Many structural choices have been made in order to keep this option open, but it is not simple to do.

§4. Thus the modules are not all produced at the same time, and several are produced independently. The module for each kit, in particular, is essentially compiled as a stand-alone Inter program and only joins the finished program at the linking stage.

+-------------------------------+   +---------------------+   +---------------------+
|   architecture                |   |   architecture      |   |   architecture      |
|   generic                     |   |   BasicInformKit    |   |   WorldModelKit     |
|   source_text                 |   |   connectors        |   |   connectors        |
|   locksmith_by_emily_short    |   +----------+----------+   +----------+----------+
|   ...                         |      INTER   |                 INTER   |
|   completion                  |              |                         |
|   connectors                  |              |                         |   ...
+------------------+------------+              |                         |
    INFORM7         \                          |                         |
                     \                        \|/                       \|/
                      \----------------------->o----------->o<-----------o---- ...
                                                            |
                                                            | INTER
                                                            |
                                                           \|/
                                            +---------------+---------------+
                                            |   architecture                |
                                            |   generic                     |
                                            |   source_text                 |
                                            |   locksmith_by_emily_short    |
                                            |   ...                         |
                                            |   completion                  |
                                            |   BasicInformKit              |
                                            |   WorldModelKit               |
                                            |   ...                         |
                                            |   synoptic                    |
                                            |   connectors                  |
                                            +-------------------------------+

§5. Modules subdivide the program by origin. But each module is further subdivided into "submodules", packages of type _submodule, and those divide it by its ingredients. For example, the global variables in module M will all be in the submodule /main/M/variables.

At present, the full range of possible subpackages is:

    /main/M/actions
    /main/M/activities
    /main/M/adjectives
    /main/M/arrays
    /main/M/basics
    /main/M/bibliographic
    /main/M/chronology
    /main/M/commands
    /main/M/conjugations
    /main/M/constants
    /main/M/extensions
    /main/M/functions
    /main/M/grammar
    /main/M/instances
    /main/M/interactive_fiction
    /main/M/kinds
    /main/M/multimedia
    /main/M/phrases
    /main/M/properties
    /main/M/relations
    /main/M/responses
    /main/M/rulebooks
    /main/M/rules
    /main/M/scenes
    /main/M/table_columns
    /main/M/tables
    /main/M/tests
    /main/M/text
    /main/M/use_options
    /main/M/variables

§6. Metadata is extensively used throughout Inter trees generated by Inform. This is not simply to serve human readers who happen to be glancing at them: it's essential to the process that generous and systematic metadata is present, because both the synoptic module and the index1 for a project are both generated using that metadata.

§7. As an example, every module includes metadata at its top level like so:

    package main _plain
        ...
        package basic_inform_by_graham_nelson _module
            constant (int32) ^category = 3
            constant (text) ^author = "Graham Nelson"
            constant (text) ^title = "Basic Inform"
            constant (text) ^version = "1"
            constant (text) ^credit = "Basic Inform version 1 by Graham Nelson"
            constant (int32) ^modesty = 0
            constant (int32) ^word_count = 7691
            ...

§8. Function packages. All functions are expressed in Inter code by packages of type _function. This contains the function body as a subpackage, but it may also contain resources needed by that function body — for example, literal texts, arrays and so on. (The idea is that a _function package can be "transmigrated" from one tree to another, without losing the resources it depends on.)

Usually this _function package will contain only one function body, often but not always called just call:

                package rule_fn _function
                    package call _code
                        ...

But if the function needs to manipulate or refer to data not expressible in single words, such as lists or texts, then it will probably need to create and subsequently destroy a stack frame. The mechanism will then be:

                package rule_fn _function
                    package call _code
                        ...
                    package kernel _code
                        ...

The "shell" function, call, creates a stack frame and then calls the "kernel" function, which does the actual work; when that returns to the "shell", the stack frame is disposed of again. This is all transparent to the user, who simply calls call and doesn't need to know which mechanism is in play.

§9. Looking at the Inter produced. The following commands produce the final state of the Inter code for the test case Acidity, in binary and textual form:

$ 'inform7/Tangled/inform7' -source inform7/Tests/Test\ Cases/Acidity.txt -o Acidity.interb -format=binary
$ 'inform7/Tangled/inform7' -source inform7/Tests/Test\ Cases/Acidity.txt -o Acidity.intert -format=text

Be warned that these are large: they have several large kits linked into them by the time they have reached this final state, and thus contain many modules. Acidity.intert runs to about 250,000 lines of textual Inter.

It's also possible to access the Inter output by the top half of inform7 before it passes through any linking process: simply add -pipeline unlinked. Unlike the default pipeline -pipeline compile, unlinked just saves out the Inter straight to an external file. (Of course, saving out unlinked Inter to a format like Inform 6 will not produce viable code: linking is done for a reason.)