This file is part of the TADS 2 Authors Manual.
Copyright © 1987 - 2002 by Michael J. Roberts.
All rights reserved.
The manual was converted to HTML and edited by NK Guy, tela design.
This chapter describes how to use the TADS Compiler, and explains the options and parameters that the compiler accepts.
The TADS Compiler is the program that reads your adventure source file, checks it for correct syntax, and converts it to a binary representation that can be executed by the TADS run-time system. Generally, the binary version of your game is considerably smaller than the source. The symbolic TADS code is converted to a byte-code similar to machine language, the strings are compressed using a variable byte length encoding (which also makes it difficult for players to cheat by looking at your programs strings), and the objects are converted to compact data structures.
This section describes the options and parameters that you use to control the TADS Compiler. Note that the format of the commands shown in this section is general, and some operating systems may have slightly different conventions; consult your system-specific release notes for information on using the Compiler on your computer. Note also that you may have to perform some minor configuration on your computer (for example, setting the command path so that your command interpreter can find the Compiler program file) before you can run the Compiler.
Note that on Macintosh systems, the compiler does not have a command line at all; instead, it uses a dialogue box and pull-down menus to specify compiler options. All of the options described in this appendix are accessible in the Macintosh version; it should be easy to identify the menu selections and dialog entries corresponding to the options described below.
The Macintosh compiler also does not add default suffix to input files. In past versions, the compiler added .t to the name of a source file if the source file didnt have any periods in its name. While adding a default suffix is convenient on other platforms (since it saves the user the trouble of typing the suffix on the command line), its obviously not desirable on the Macintosh, since the user specifies the file by pointing at it - the full filename is always given, so a suffix shouldnt be added.
You can run the TADS Compiler simply by typing its name, tc or tc32 or tadsc, followed by the name of the file you want to compile. (the exact name depends on the version youre running and for what operating system) For example:
tc sampleThis invokes the TADS Compiler, and tells it to compile the file sample.t (using the appropriate local conventions to add the extension .t to the given filename), and to write the binary version of the game to the file sample.gam.
If any errors occur during compilation, the Compiler provides an explanatory message and tells you the file and line number where the error occurred. If errors (other than warnings) occur, the binary file is not created, since the game would not be playable. (On Macintosh systems the compiler also displays the text of lines at which errors are detected.)
Text-only versions of the TADS Compiler accept several options as part of the command to control operation. All of the options consist of a dash, followed by one or more option letters, possibly followed by a parameter. The options are specified before the name of the source file:
tc options fileFor example, to compile sample.t and generate source-level debugging information, you would type this command:
tc -ds sampleNote that with options that take a parameter, you can either run the option and its parameter together without a space, or you can put a space between them; it makes no difference. For example, the following two commands are equivalent:
tc -ic:\tads -od:sample sample tc -i c:\tads -o d:sample sampleNote, however, that the memory options require the memory type letter immediately after the -m option; the size, however, can be separated by a space. Hence, the following two commands are valid:
tc -mh5000 sample tc -mh 5000 sampleFollowing is the complete list of Compiler options. For a brief list of the options, just type tc without any parameters; the Compiler will display a list of the options it accepts and what they do. Note that versions of the Compiler with a graphical interface (Macintosh and Windows) have menu items which allow you to set most or all of these options without any typing in of commands.
The TADS Compiler has a number of memory options related to certain internal settings. Most versions of the compiler ship with these options preset to reasonable defaults, so its unlikely youll run into problems with the settings being too low. However, the default values do vary between certain versions of the compiler, so it may be necessary to experiment with some of these memory options, particularly if youre compiling a really large (a megabyte or more of source code) game or if youre using a very old computer with very limited memory. The parse node pool setting is the most likely option that will need adjusting in those cases.
The compiler checks carefully to ensure that the memory size settings specified with the various -m parameters (in particular, -mg, -mp, -ml, -ms, and -mh) are valid. These settings must fit within certain limits, which are enforced carefully. Previous versions of the compiler responded unpredictably to invalid settings.
goto label table size (-mg)
This setting controls the size of an internal table used to keep track of goto labels within a function. You probably will never need to adjust this setting - especially if you never use goto anywhere in your code.
The size affects each function individually, so you only need to set it as large as necessary to accommodate whichever of your functions has the most goto labels. The actual number of bytes needed is the sum of the number of characters in all of the label names in a function, plus some overhead per label.
The default for this setting is usually 1024 or 8192 bytes. The maximum value is 64K, but there should be never be any reason to set it this high unless youre dangerously obsessed with goto statements.
Local symbol table size (-ml)
This is an internal table that the compiler uses to track local variable definitions. Like the goto table, this is used for functions individually, so it scales according to your largest function (ie: the one with the most locals), not with the overall program size.
The default for this setting is usually 4096 or 16384 bytes. Note that the values for the local symbol table and parse node pool table are linked - the combined value of the two tables cannot exceed 64K.
Parse node pool size (-mp)
The parse node pool is another internal table, and probably the only memory setting youre likely to need to change if youre compiling a very large game.
This table is used by the compiler for temporary storage of internal data structures required to parse expressions. The memory required generally scales according to the complexity of expressions (such as variable assignments, if conditions, while control expressions, and the like). In addition, some types of statements have to keep track of several expressions at once, so the complexity compounds; for statements and nested switch statements, for example, tend to keep several expressions worth of data at once.
The default for this setting is usually 6144 bytes or 24576 bytes. The latter should be more than adequate to compile even really huge games. Note that the values for the local symbol table and parse node pool table are linked - you cant have a combined value of greater than 64K for the two tables.
Heap size (-mh)
This setting has exactly the same function as the interpreters heap size - the compiler uses it for configuring the integrated interpreter it uses to run the preinit function. This is the area where the interpreter builds intermediate values for string and list operations, such as extracting a substring or appending data to a list.
The default for this setting is usually 1024 bytes or 65535 bytes; the latter being its maximum value.
Stack size (-ms)
This setting has exactly the same function as the interpreters interpreter stack, and like the heap is used for running preinit. The size needed here depends on how deeply nested your function calls are while running preinit.
The default for this setting is usually 50 or 512 elements, and the maximum varies from system to system but usually tops out at 8000 elements.
Virtual object cache (-m)
This is the memory area that the compiler uses to contain the compiled representation of game objects and functions. Since the compiler has a virtual memory system, the cache size can be smaller than the actual memory needs of your game. Normally, you will not need to set the cache size, since the compiler automatically allocates additional memory for the cache as needed.
However, since the compiler also allocates non-cache memory during compilation, the cache can grow so large that, in low-memory situations, your computer runs out of space for non-cache memory. If this happens, the compiler will exit and issue an error message telling you how big the cache was when the compiler ran out of non-cache memory; you should re-run the compiler specifying a smaller size with the -m parameter. For example, if the compiler runs out of memory and tells you that the cache is 256,000 bytes, you could try re-running with -m 200000 to specify that the cache should grow no larger than 200,000 bytes.
Some versions of the compiler (eg: Macintosh) do not let you adjust this setting - its permanently set to the highest value. In this case you may need to expand the amount of memory available to the compiler program if your computers operating system doesnt do it for you automatically. For example, under versions of the MacOS through to OS 9.x you will need to increase the amount of memory allocated to the compiler program by going to the programs Get Info box.
On non-graphical operating systems, the TADS compiler allows you to place a set of command line options into a configuration file that is read each time the compiler is run. This file is named CONFIG.TC. TADS looks for this file first in the current directory, and if it fails to find it, in the same directory as your TADS Compiler executable. This allows you to have multiple configurations: one default configuration, stored in the CONFIG.TC file in your TADS compiler directory; and then special per-game configurations, stored in the CONFIG.TC files in your game source directories. If the file does not exist in either the current directory or in the TADS compiler directory, no configuration file is used.
The configuration file simply contains compiler options. The file is a standard text file; each line within the file can have as many options as you want, and the file can have as many lines as you want. Any blank lines within the file are ignored.
If you want to create a configuration file that specifies that the virtual object cache is to be limited to 128,000 bytes, that the swap file is to be named SWAP.DAT on the D: disk, and that the directory c:\tads\include is to be searched for header files, you could make a configuration file like this:
-m 128000 -tf d:\swap.dat -I c:\tads\includeNote that options specified on the command line always override options in the configuration file. The configuration file is simply a convenient way to store default options that you often use. Suppose you are using the above configuration file, and you type this command:
tc -m 256000 -I c:\myinc mygame.tThe -m 256000 option overrides the configuration files -m 128000 option, so the configuration files version is ignored. Include directory options are a little different, in that theyre additive: the command lines -I c:\myinc is added to the include path. However, since the command line takes precedence over the configuration file, the command line include path is added before the path in the configuration file.
You are not required to use a configuration file, and no error is generated if a configuration file is not found. The configuration file is simply a convenient way to store options that you frequently use, so you dont have to type them every time you run the compiler.
Version 2.2 of TADS introduced a slightly different game file format than that used by previous versions, and version 2.1 introduced another format. The newer formats will not be acceptable to older versions of the interpreter, although the new run-times are able to read .GAM files produced by older versions of the compiler.
The version 2.2 compiler generates .GAM files with format C; the version 2.1 compiler generated .GAM files with format B and prior versions generated format A. The version 2.2 interpreter is able to read files in all three formats. Previous versions cannot read all three formats.
If for some reason you wish to generate a .GAM file that can be read by an older version of the interpreter, the compiler has a new option, -fva (Format Version A) which generates .GAM files in the old format A. Similarly you can use -fvb (Format Version B) to generate format B games.
Unless you have a specific need to generate the older formats, we recommend using the newest format (which the compiler will use by default). Another switch, -fvc, is provided to tell the compiler explicitly to use format C; and -fv* tells the compiler to use the most recent format (currently C).
Note that some incompatible file format changes have been made in past versions in such a way that the interpreter is unable to detect the incompatibility. It is therefore not always safe to mix different versions of the compiler and interpreter with versions prior to 2.1.
One of the changes to the game file format B makes the files much more compressible with archiving and compression utilities. The .ZIP and .SIT files that you make from your .GAM files should now be much smaller.
The changes made in version C enable the disambigDobjFirst flag. If you compile with an earlier file format, you will not be allowed to use this flag.
When the compiler encounters a semicolon or a right brace (}) in the first column of a line while inside a string (either double-quoted or single-quoted), it will generate a warning message that you have a possible unterminated string. This is purely a guess by the compiler, but if you are careful to format your code using the same convention as adv.t, in which every function ends with a right brace on a line by itself, and every object ends with a semicolon on a line by itself (without any spaces preceding it), the compiler will be able to find your unterminated strings almost every time. Note that the unterminated string will often not be the last string, but this warning will at least isolate the object or function where the string is coded.
The compiler will generate an error message if you attempt to use self in a function. This has always been illegal, but versions of the compiler prior to 2.1 did not detect the error, so the problem was not detected until the code was actually executed.
The warning messages that the compiler generates for optional objects and functions (such as parseError and commandPrompt) are suppressed at warning verbosity levels less than 2. Many users find these warnings confusing or annoying, and they almost never actually indicate a problem in your game, so they are not generated unless you specifically ask for them.
The warning message for multiple inclusions of the same file is suppressed at verbosity levels less than 1. This message is almost always spurious if you use precompiled headers, because it is generated for every header that you precompiled. You will not see this warning unless you specifically ask for it by setting a higher warning verbosity level.
We must learn to explore all the options and possibilities
that confront us in a complex and rapidly changing world.
JAMES WILLIAM FULLBRIGHT, Speech in the Senate (1964)
| Appendix B | Table of Contents | Appendix D |