1
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
4
<title>DM4 §38: Controlling compilation from within</title>
5
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
6
<link rel="stylesheet" type="text/css" href="dm4.css">
10
<a href="index.html">home</a> /
11
<a href="contents.html">contents</a> /
12
<a href="ch6.html" title="Chapter VI: Using the Compiler">chapter VI</a> /
13
<a href="ch6.html" title="Chapter VI: Using the Compiler">prev</a> /
14
<a href="s39.html" title="§39: Controlling compilation from without">next</a> /
15
<a href="dm4index.html">index</a>
18
<a id="p288" name="p288"></a>
19
<h2>§38 Controlling compilation from within</h2>
21
<p class="normal"><span class="atleft"><img src="dm4-288_1.jpg" alt=""></span>
22
Inform has a number of directives for controlling which pieces of
23
source code are compiled: for instance, you can divide your source
24
code into several files, compiled together or separately, or you can
25
write source code in which different passages will be compiled on
26
different occasions. Most of these directives are seldom seen, but almost every
29
<p class="lynxonly"></p>
30
<pre class="code">Include "filename";</pre>
32
<p class="normal">which instructs Inform to glue the whole of that source
33
code file into the program right here. It is exactly equivalent to removing
34
the <code>Include</code> directive and replacing it with the whole file
35
<tt>"filename"</tt>. (The rules for how Inform interprets
36
<tt>"filename"</tt> vary from machine to machine: for instance,
37
it may automatically add an extension such as “<tt>.inf</tt>”
38
if your operating system normally uses filename extensions and it may
39
look in some special directory. Run Inform with the <tt>-h1</tt> switch
40
for further information.) Note that you can write</p>
42
<p class="lynxonly"></p>
43
<pre class="code">Include ">shortname";</pre>
45
<p class="normal">to mean “the file called <tt>"shortname"</tt>
46
which is in the same directory that the present file came from”.
47
This is convenient if all the files making up the source code of your
48
game are housed together.</p>
50
<p class="indent">Next, there are a number of “conditional compilation”
51
directives. They take the general form of a condition:</p>
53
<p class="lynxonly"></p>
54
<a id="p289" name="p289"></a>
55
<div class="inset"><table>
56
<tr><td><code>Ifdef</code> ‹<span class="token">name</span>›<code>;</code></td>
57
<td>Is ‹<span class="token">name</span>› defined as having some meaning?</td></tr>
58
<tr><td><code>Ifndef</code> ‹<span class="token">name</span>›<code>;</code></td>
59
<td>Is ‹<span class="token">name</span>› undefined?</td></tr>
60
<tr><td><code>Iftrue</code> ‹<span class="token">condition</span>›<code>;</code></td>
61
<td>Is this ‹<span class="token">condition</span>› true?</td></tr>
62
<tr><td><code>Iffalse</code> ‹<span class="token">condition</span>›<code>;</code></td>
63
<td>Is this ‹<span class="token">condition</span>› false?</td></tr>
66
<p class="normal">followed by a chunk of Inform and then, optionally,</p>
68
<p class="lynxonly"></p>
69
<pre class="code">Ifnot;</pre>
71
<p class="normal">and another chunk of Inform; and finally</p>
73
<p class="lynxonly"></p>
74
<pre class="code">Endif;</pre>
76
<p class="normal">At this point it is perhaps worth mentioning that
77
(most) directives can also be interspersed with statements in routine
78
declarations, provided they are preceded by a <code>#</code> sign.
81
<p class="lynxonly"></p>
84
#Iftrue MAX_SCORE > 1000;
85
print "My, what a long game we're in for!^";
87
print "Let's have a quick game, then.^";
93
<p class="normal">which actually only compiles one of the two print
94
statements, according to what the value of the constant <code>MAX_SCORE</code>
97
<p class="aside"><span class="warning">▲</span>
98
One kind of “if-defined” manoeuvre is so useful that it
99
has an abbreviation:</p>
101
<p class="syntax"><code>Default</code>
102
‹<span class="token">name</span>›
103
‹<span class="token">value</span>›<code>;</code></p>
105
<p class="aside">defines ‹<span class="token">name</span>›
106
as a constant if it wasn't already the name of something: so it's
109
<p class="syntax"><code>Ifndef</code>
110
‹<span class="token">name</span>›<code>; Constant</code>
111
‹<span class="token">name</span>› <code>=</code>
112
‹<span class="token">value</span>›<code>; Endif;</code></p>
114
<p class="aside">Similarly, though far less often used,
115
<code>Stub <name> <number>;</code> defines a do-nothing
116
routine with this name and number (0 to 3) of local variables,
117
if it isn't already the name of something: it is equivalent to</p>
119
<p class="syntax"><code>Ifndef</code>
120
‹<span class="token">name</span>›<code>; [</code>
121
‹<span class="token">name</span>›
122
<code>x1 x2</code> …
123
<code>x</code>‹<span class="token">number</span>›<code>; ]; Endif;</code></p>
125
<a id="p290" name="p290"></a>
126
<p class="dotbreak">� � � � �</p>
128
<p class="normal">Large standard chunks of Inform source code are often
129
bundled up into “libraries” which can be added to any
130
Inform story file using the <code>Include</code> directive. Almost
131
all Inform adventure games include three library files called
132
“Parser”, “VerbLib” and “Grammar”,
133
and several dozen smaller libraries have also been written.
134
Sometimes, though, what you want to do is “include all of this
135
library file except for the definition of <code>SomeRoutine</code>”.
136
You can do this by declaring:</p>
138
<p class="lynxonly"></p>
139
<pre class="code">Replace SomeRoutine;</pre>
141
<p class="normal">before the relevant library file is included. You
142
still have to define your own <code>SomeRoutine</code>, hence the
143
term “replace”.</p>
145
<p class="aside"><span class="warning">▲▲</span>
146
How does Inform know to ignore the <code>SomeRoutine</code> definition
147
in the library file, but to accept yours as valid? The answer is that
148
a library file is marked out as having routines which can be replaced,
149
by containing the directive</p>
151
<p class="lynxonly"></p>
152
<pre class="code">System_file;</pre>
154
<p class="aside">All eight of the standard Inform library files (the
155
three you normally <code>Include</code> in games, plus the five others
156
which they <code>Include</code> for you) begin with this directive.
157
It also has the effect of suppressing all compilation warnings
158
(but not errors) arising from the file.</p>
160
<p class="dotbreak">� � � � �</p>
162
<p class="normal">One way to follow what is being compiled is to use the
163
<code>Message</code> directive. This makes the compiler print messages
166
<p class="lynxonly"></p>
168
Message "An informational message";
169
Message error "An error message";
170
Message fatalerror "A fatal error message";
171
Message warning "A warning message";
174
<p class="normal">Errors, fatal errors and warnings are treated as if
175
they had arisen from faults in the source code in the normal way. See
176
<a href="s40.html">§40</a> for more about the kinds of error
177
Inform can produce, but for now, note that an error or fatal error will
178
prevent any story file from being produced, and that messages issued
179
by <code>Message warning</code> will be suppressed if they occur in
180
a “system file” (one that you have marked with a
181
<code>System_file</code> directive). Informational messages are
184
<p class="lynxonly"></p>
185
<pre class="code">Message "Geometry library by Boris J. Parallelopiped";</pre>
187
<p class="normal">prints this text, followed by a new-line.</p>
189
<a id="p291" name="p291"></a>
190
<p class="aside"><span class="warning">▲</span>
191
One reason to use this might be to ensure that a library file fails
192
gracefully if it needs to use a feature which was only introduced on
193
a later version of the Inform compiler than the one it finds itself
194
running through. For example:</p>
196
<p class="lynxonly"></p>
200
"The geometry extension needs Inform 6.1 or later";
204
<p class="aside">By special rule, the condition “<code>VN_1610</code>
205
is defined” is true if and only if the compiler's release number
206
is 6.10 or more; similarly for the previous releases 6.01, first to
207
include message-sending, 6.02, 6.03, 6.04, 6.05, 6.10, which expanded
208
numerous previous limits on grammar, 6.11, 6.12, which allowed Inform
209
to read from non-English character sets, 6.13, 6.15, which allowed
210
parametrised object creation, 6.20, which introduced strict error checking,
211
and finally (so far) 6.21, the first to feature Infix. A full history
212
can be found in the <i>Technical Manual</i>.</p>
214
<p class="dotbreak">� � � � �</p>
216
<p class="normal">Inform also has the ability to link together separately-compiled
217
pieces of story file into the current compilation. This feature is provided
218
primarily for users with slowish machines who would sooner not waste time
219
compiling the standard Inform library routines over and over again. Linking
220
isn't something you can do entirely freely, though, and if you have a fast
221
machine you may prefer not to bother with it: the time taken to compile
222
a story file is now often dominated by disc access times, so little
223
or no time will be saved.</p>
225
<p class="indent">The pieces of pre-compiled story file are called “modules”
226
and they cannot be interpreted or used for anything other than linking.</p>
228
<p class="indent">The process is as follows. A game being compiled (called
229
the “external” program) may <code>Link</code> one or more
230
pre-compiled sections of code called “modules”. Suppose
231
the game Jekyll has a subsection called Hyde. Then these two methods
232
of making Jekyll are, very nearly, equivalent:</p>
234
<ol style="list-style-type:decimal">
235
<li>Putting <code>Include "Hyde";</code> in the source for
236
<tt>"Jekyll"</tt>, and compiling <tt>"Jekyll"</tt>.</li>
237
<li>Compiling <tt>"Hyde"</tt> with the <tt>-M</tt>
238
(“module”) switch set, then putting <code>Link "Hyde";</code>
239
into the same point in the source for <tt>"Jekyll"</tt>, and
240
compiling <tt>"Jekyll"</tt>.</li>
243
<p class="normal">Option (2) is faster as long as <tt>"Hyde"</tt>
244
does not change very often, since its ready-compiled module can be
245
left lying around while <tt>"Jekyll"</tt> is being developed.</p>
247
<p class="indent">Because “linking the library” is by far
248
the most common use of the linker, this is made simple. All you have to
249
do is compile your game with the <tt>-U</tt>
250
<a id="p292" name="p292"></a>
251
switch set, or, equivalently, to begin your source code with</p>
253
<p class="lynxonly"></p>
254
<pre class="code">Constant USE_MODULES;</pre>
256
<p class="normal">This assumes that you already have pre-compiled copies
257
of the two library modules: if not, you'll need to make them with</p>
259
<p class="lynxonly"></p>
261
inform -M library/parserm.h
262
inform -M library/verblibm.h
265
<p class="normal">where <tt>library/parserm.h</tt> should be replaced with
266
whatever filename you keep the library file “<tt>parserm</tt>”
267
in, and likewise for “<tt>verblibm</tt>”. This sounds
268
good, but here are four caveats:</p>
270
<ol style="list-style-type:decimal">
271
<li>You can only do this for a game compiled as a Version 5 story file.
272
This is the version Inform normally compiles to, but some authors
273
of very large games need to use Version 8. Such authors usually have
274
relatively fast machines and don't need the marginal speed gain from
275
linking rather than including.</li>
276
<li>It's essential not to make any <code>Attribute</code> or
277
<code>Property</code> declarations <em>before</em> the <code>Include
278
"Parser"</code> line in the source code, though <em>after</em>
279
that point is fine. Inform will warn you if you get this wrong.</li>
280
<li>Infix debugging, <tt>-X</tt>, is not compatible with linking, and
281
strict error checking <tt>-S</tt> does not apply within modules.</li>
282
<li>The precompiled library modules always include the <tt>-D</tt>
283
debugging verbs, so when you come to compile the final release version
284
of a game, you'll have to compile it the slow way, i.e., without linking
288
<p class="aside"><span class="warning">▲▲</span>
289
If you intend to write your own pre-compilable library modules, or
290
intend to subdivide a large game into many modular parts, you will need
291
to know what the limitations are on linking. (In the last recourse you
292
may want to look at the <i>Technical Manual</i>.) Here's a brief list:</p>
294
<ol style="list-style-type:decimal">
295
<li>The module must make the same <code>Property</code> and
296
<code>Attribute</code> directives as the main program and in the
297
same order. Including the library file <tt>"linklpa.h"</tt>
298
(“link library properties and attributes”) declares the
299
library's own stock, so it might be sensible to do this first, and
300
then include a similar file defining any extra common properties and
301
attributes you need.</li>
302
<li>The module cannot contain grammar (i.e., use <code>Verb</code>
303
or <code>Extend</code> directives) or create “fake actions”.</li>
304
<li>The module can only use global variables defined outside the module
305
if they are explicitly declared before use using the <code>Import</code> directive.
306
For example, writing <code>Import global frog;</code> allows the rest
307
of the module's source code to refer to the
308
<a id="p293" name="p293"></a>
309
variable <code>frog</code>
310
(which must be defined in the outside program). Note that the Include
311
file <tt>"linklv.h"</tt> (“link library variables”)
312
imports all the library variables, so it would be sensible to include
314
<li>An object in the module can't inherit from a class defined outside
315
the module. (But an object outside can inherit from a class inside.)</li>
316
<li>Certain constant values in the module must be known at module-compile-time
317
(and must not, for instance, be a symbol only defined outside the module).
318
For instance: the size of an array must be known now, not later; so
319
must the number of duplicate members of a <code>Class</code>; and
320
the quantities being compared in an <code>Iftrue</code> or
321
<code>Iffalse</code>.</li>
322
<li>The module can't: define the <code>Main</code> routine; use
323
the <code>Stub</code> or <code>Default</code> directives; or define
324
an object whose parent object is not also in the same module.</li>
327
<p class="aside">These restrictions are mild in practice. As an example,
328
here is a short module to play with:</p>
330
<p class="lynxonly"></p>
332
Include "linklpa"; ! Make use of the properties, attributes
333
Include "linklv"; ! and variables from the Library
335
objectloop (x has light)
336
print (The) x, " is currently giving off light.^";
340
<p class="aside">It should be possible to compile this <tt>-M</tt> and then
341
to <code>Link</code> it into another game, making the routine
342
<code>LitThings</code> exist in that game.</p>
344
<p class="dotbreak">� � � � �</p>
346
<p class="normal">Every story file has a release number and a serial
347
code. Games compiled with the Inform library print these numbers
348
in one line of the “banner”. For instance, a game compiled
349
in December 1998 might have the banner line:</p>
351
<p class="output">Release 1 / Serial number 981218 / Inform v6.20 Library 6/8</p>
353
<p class="normal">The release number is 1 unless otherwise specified with the directive</p>
355
<p class="lynxonly"></p>
356
<pre class="code">Release <number>;</pre>
358
<p class="normal">This can be any Inform number, but convention is for
359
the first published copy of a game to be numbered 1, and releases 2,
360
3, 4,… to be amended re-releases.</p>
362
<p class="indent">The serial number is set automatically to the date
363
of compilation in the form “yymmdd”, so that <code>981218</code> means
364
“18th December 1998” and <code>000101</code> means
365
“1st January 2000”. You can fix the date differently by setting</p>
367
<p class="lynxonly"></p>
368
<pre class="code">Serial "dddddd";</pre>
370
<p class="normal">where the text must be a string of 6 (decimal) digits.
371
Inform's standard example games do this, so that the serial number will
372
be the date of last modification of the source code, regardless of
373
when the story file is eventually compiled.</p>
375
<a id="p294" name="p294"></a>
376
<p class="aside"><span class="warning">▲</span>
377
The Inform release number is written into the story file by Inform
378
itself, and you can't change it. But you can make the story file print
379
out this number with the special statement <code>inversion;</code>.</p>
383
<a href="index.html">home</a> /
384
<a href="contents.html">contents</a> /
385
<a href="ch6.html" title="Chapter VI: Using the Compiler">chapter VI</a> /
386
<a href="ch6.html" title="Chapter VI: Using the Compiler">prev</a> /
387
<a href="s39.html" title="§39: Controlling compilation from without">next</a> /
388
<a href="dm4index.html">index</a>