DM4 §39: Controlling compilation from without

## §39 Controlling compilation from without

The Inform compiler has the equivalent of a dashboard of “command line switches”, controlling its behaviour. Most of these have only two settings, off or on, and most of them are off most of the time. Others can be set to a number between 0 and 9. In this book switches are written preceded by a minus sign, just as they would be typed if you were using Inform from the command line of (say) Unix or RISC OS. Setting `-x`, for instance, causes Inform to print a row of hash signs as it compiles:

`inform -x shell
RISC OS Inform 6.20 (10th December 1998)
::##############################################################
#################`

One hash sign is printed for every 100 textual lines of source code compiled, so this row represents about eight thousand lines. (During the above compilation, carried out by an Acorn Risc PC 700, hashes were printed at a rate of about thirty per second.) `-x` is provided not so much for information as to indicate that a slow compilation is continuing normally. Contrariwise, the `-s` switch offers more statistics than you could possibly have wanted, as in the following monster compilation (of ‘Curses’):

    RISC OS Inform 6.20 (10th December 1998)
    In: 25 source code files           17052 syntactic lines
     22098 textual lines              860147 characters (ISO 8859-1 Latin1)
    Allocated:
      1925 symbols (maximum 10000)   1022182 bytes of memory
    Out:  Version 8 "Extended" story file 17.981218 (343.5K long):
        37 classes (maximum 64)          579 objects (maximum 639)
       169 global vars (maximum 233)    4856 variable/array space (m. 8000)
       153 verbs (maximum 200)          1363 dictionary entries (m. 2000)
       318 grammar lines (version 2)     490 grammar tokens (unlimited)
       167 actions (maximum 200)          34 attributes (maximum 48)
        51 common props (maximum 62)     153 individual props (unlimited)
    267892 characters used in text    195144 bytes compressed (rate 0.728)
         0 abbreviations (maximum 64)    891 routines (unlimited)
     25074 instructions of Z-code      10371 sequence points
     52752 bytes readable memory used (maximum 65536)
    351408 bytes used in Z-machine    172880 bytes free in Z-machine
    Completed in 8 seconds

The complete list of switches is listed when you run Inform with `-h2`, and also in Table 3 at the back of this book, where there are notes on some of the odder-looking ones.

When the statistics listing claims that, for instance, the maximum space for arrays is 10,000, this is so because Inform has only allocated enough memory to keep track of 10,000 entries while compiling. This in turn is because Inform's “memory setting” `$MAX_STATIC_DATA` was set to 10,000 when the compilation took place.

Between them, the “memory settings” control how much of your computer's memory Inform uses while running. Too little and it may not be able to compile games of the size you need, but too much and it may choke any other programs in the computer for space. It's left up to you to adjust the memory settings to suit your own environment, but most people leave them alone until an error message advises a specific increase.

Finally, Inform has “path variables”, which contain filenames for the files Inform uses or creates. Usage of these varies widely from one operating system to another. Run Inform with the `-h1` switch for further information.

· · · · ·

Inform's switches, path variables and memory settings are set using “Inform Command Language” or ICL. The usual way to issue ICL commands, at least on installations of Inform which don't have windowed front-ends, is to squeeze them onto the command line. The standard command line syntax is

`inform` ‹ICL commands› ‹source file› ‹output file›

where only the ‹source file› is mandatory. By default, the full names to give the source and output files are derived in a way suitable for the machine Inform is running on: on a PC, for instance, `advent` may be understood as asking to compile `advent.inf` to `advent.z5`. This is called “filename translation”. No detailed information on filenaming rules is given here, because it varies so much from machine to machine: see the `-h1` on-line documentation. Note that a filename can contain spaces if it is written in double-quotes and if the operating system being used can cope with spaces (as Mac OS can, for instance).

To specify sprawling or peculiar projects may need more ICL commands than can fit comfortably onto the command line. One possible ICL command, however, is to give a filename in (round) brackets: e.g.,

    inform -x (skyfall_setup) ...

which sets the `-x` switch, then runs through the text file `skyfall_setup` executing each line as an ICL command. This file then look like this:

    ! Setup file for "Skyfall"
    -d                   ! Contract double spaces
    $max_objects=1000    ! 500 of them snowflakes
    (usual_setup)        ! include my favourite settings, too
    +module_path=mods    ! keep modules in the "mods" directory

ICL can include comments if placed after `!`, just as in Inform. Otherwise, an ICL file has only one command per line, with no dividing semicolons. Using ICL allows you to compile whole batches of files as required, altering switches, path variables and memory settings as you go. Notice that ICL files can call up other ICL files, as in the example above: don't allow a file to call up another copy of itself, or the compilation will all end in tears.

▲ When typing such a command into a shell under a Unix-like operating systems, you may need to quote the parentheses:

    inform -x '(skyfall_setup)' ...

This instructs the shell to pass on the command literally to Inform, and not to react to unusual characters like `$`, `?`, `(` or `)` in it. The same may be needed for other ICL commands such as:

    inform -x '$MAX_OBJECTS=2000' ...

▲ Windowed front-ends for Inform sometimes work by letting the user select various options and then, when the “Go” button is pressed, convert the state of the dialogue box into an ICL file which is passed to Inform.

▲▲ If you need to use Inform without benefit of either a command line or a fancy front-end, or if you want your source code to specify its own switch settings, you can still set (most) switches by placing the directive

`Switches` ‹some settings›`;`

at the very beginning of your source code. (So that you can still override such settings, the switch `-i` tells Inform to ignore all `Switches` directives.)

· · · · ·

The ICL commands are as follows:

`-`‹switches›
Set these switches; or unset any switch preceded by a tilde `~`. (For example, `-a~bc` sets `a`, unsets `b` and sets `c`.)

`$list`
List current memory settings.

`$?`‹name›
Ask for information on what this memory setting is for.

`$small`
Set the whole collection of memory settings to suitable levels for a small game.

`$large`
Ditto, for a slightly larger game.

`$huge`
Ditto, for a reasonably big one.

`$`‹name›`=`‹quantity›
Alter the named memory setting to the given level.

`+`‹name›`=`‹filename›
Set the named pathname variable to the given filename, which should be one or more filenames of directories, separated by commas.

`compile` ‹filename› ‹filename›
Compile the first-named file, containing source code, writing the output program to the (optional) second-named file.

`(`‹filename›`)`
Execute this ICL file (files may call each other in this way).

· · · · ·

It's a nuisance to have to move all the memory settings up or down to cope with a big game or a small computer, so `$small`, `$large` and `$huge` are provided as short cuts. Typically these might allocate 350K, 500K or 610K respectively. Running

    inform $list

will list the various settings which can be changed, and their current values. Thus one can compare small and large with:

    inform $small $list
    inform $large $list

If Inform runs out of allocation for something, it will generally print an error message like:

    "Game", line 1320: Fatal error: The memory setting MAX_OBJECTS
    (which is 200 at present) has been exceeded.  Try running Inform
    again with $MAX_OBJECTS=<some-larger-number> on the command line.

and it would then be sensible to try

    inform $MAX_OBJECTS=250 game

which tells Inform to try again, reserving more memory for objects this time. ICL commands are followed from left to right, so

    inform $small $MAX_ACTIONS=200 ...

will work, but

    inform $MAX_ACTIONS=200 $small ...

will not because the `$small` changes `MAX_ACTIONS` back again. Changing some settings has hardly any effect on memory usage, whereas others are expensive to increase. To find out about, say, `MAX_VERBS`, run

    inform $?MAX_VERBS

(note the question mark) which will print some very brief comments.