~ubuntu-branches/ubuntu/vivid/inform/vivid

« back to all changes in this revision

Viewing changes to inform-6.31.1/manual/s38.html

  • Committer: Bazaar Package Importer
  • Author(s): Jan Christoph Nordholz
  • Date: 2008-05-26 22:09:44 UTC
  • mfrom: (2.1.1 lenny)
  • Revision ID: james.westby@ubuntu.com-20080526220944-ba7phz0d1k4vo7wx
Tags: 6.31.1+dfsg-1
* Remove a considerable number of files from the package
  due to unacceptable licensing terms.
* Repair library symlinks.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 
2
<html>
 
3
<head>
 
4
<title>DM4 &#167;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">
 
7
</head>
 
8
<body>
 
9
<p class="navbar">
 
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="&#167;39: Controlling compilation from without">next</a> /
 
15
 <a href="dm4index.html">index</a>
 
16
</p>
 
17
<div class="page">
 
18
<a id="p288" name="p288"></a>
 
19
<h2>&#167;38 &nbsp; Controlling compilation from within</h2>
 
20
 
 
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
 
27
game uses:</p>
 
28
 
 
29
<p class="lynxonly"></p>
 
30
<pre class="code">Include &quot;filename&quot;;</pre>
 
31
 
 
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>&quot;filename&quot;</tt>. (The rules for how Inform interprets 
 
36
<tt>&quot;filename&quot;</tt> vary from machine to machine: for instance, 
 
37
it may automatically add an extension such as &#8220;<tt>.inf</tt>&#8221; 
 
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>
 
41
 
 
42
<p class="lynxonly"></p>
 
43
<pre class="code">Include &quot;&gt;shortname&quot;;</pre>
 
44
 
 
45
<p class="normal">to mean &#8220;the file called <tt>&quot;shortname&quot;</tt> 
 
46
which is in the same directory that the present file came from&#8221;. 
 
47
This is convenient if all the files making up the source code of your 
 
48
game are housed together.</p>
 
49
 
 
50
<p class="indent">Next, there are a number of &#8220;conditional compilation&#8221; 
 
51
directives. They take the general form of a condition:</p>
 
52
 
 
53
<p class="lynxonly"></p>
 
54
<a id="p289" name="p289"></a>
 
55
<div class="inset"><table>
 
56
<tr><td><code>Ifdef</code> &#8249;<span class="token">name</span>&#8250;<code>;</code></td>
 
57
 <td>Is &#8249;<span class="token">name</span>&#8250; defined as having some meaning?</td></tr>
 
58
<tr><td><code>Ifndef</code> &#8249;<span class="token">name</span>&#8250;<code>;</code></td>
 
59
 <td>Is &#8249;<span class="token">name</span>&#8250; undefined?</td></tr>
 
60
<tr><td><code>Iftrue</code> &#8249;<span class="token">condition</span>&#8250;<code>;</code></td>
 
61
 <td>Is this &#8249;<span class="token">condition</span>&#8250; true?</td></tr>
 
62
<tr><td><code>Iffalse</code> &#8249;<span class="token">condition</span>&#8250;<code>;</code></td>
 
63
 <td>Is this &#8249;<span class="token">condition</span>&#8250; false?</td></tr>
 
64
</table></div>
 
65
 
 
66
<p class="normal">followed by a chunk of Inform and then, optionally,</p>
 
67
 
 
68
<p class="lynxonly"></p>
 
69
<pre class="code">Ifnot;</pre>
 
70
 
 
71
<p class="normal">and another chunk of Inform; and finally</p>
 
72
 
 
73
<p class="lynxonly"></p>
 
74
<pre class="code">Endif;</pre>
 
75
 
 
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. 
 
79
For example:</p>
 
80
 
 
81
<p class="lynxonly"></p>
 
82
<pre class="code">
 
83
[ MyRoutine;
 
84
#Iftrue MAX_SCORE &gt; 1000;
 
85
  print &quot;My, what a long game we're in for!^&quot;;
 
86
#Ifnot;
 
87
  print &quot;Let's have a quick game, then.^&quot;;
 
88
#Endif;
 
89
  PlayTheGame();
 
90
];
 
91
</pre>
 
92
 
 
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> 
 
95
is.</p>
 
96
 
 
97
<p class="aside"><span class="warning">&#9650;</span>
 
98
One kind of &#8220;if-defined&#8221; manoeuvre is so useful that it 
 
99
has an abbreviation:</p>
 
100
 
 
101
<p class="syntax"><code>Default</code>
 
102
&#8249;<span class="token">name</span>&#8250;
 
103
&#8249;<span class="token">value</span>&#8250;<code>;</code></p>
 
104
 
 
105
<p class="aside">defines &#8249;<span class="token">name</span>&#8250;
 
106
as a constant if it wasn't already the name of something: so it's 
 
107
equivalent to</p>
 
108
 
 
109
<p class="syntax"><code>Ifndef</code> 
 
110
&#8249;<span class="token">name</span>&#8250;<code>; Constant</code>
 
111
&#8249;<span class="token">name</span>&#8250; <code>=</code>
 
112
&#8249;<span class="token">value</span>&#8250;<code>; Endif;</code></p>
 
113
 
 
114
<p class="aside">Similarly, though far less often used, 
 
115
<code>Stub &lt;name&gt; &lt;number&gt;;</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>
 
118
 
 
119
<p class="syntax"><code>Ifndef</code> 
 
120
&#8249;<span class="token">name</span>&#8250;<code>; [</code>
 
121
&#8249;<span class="token">name</span>&#8250; 
 
122
<code>x1 x2</code> &#8230; 
 
123
<code>x</code>&#8249;<span class="token">number</span>&#8250;<code>; ]; Endif;</code></p>
 
124
 
 
125
<a id="p290" name="p290"></a>
 
126
<p class="dotbreak">� � � � �</p>
 
127
 
 
128
<p class="normal">Large standard chunks of Inform source code are often 
 
129
bundled up into &#8220;libraries&#8221; 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
&#8220;Parser&#8221;, &#8220;VerbLib&#8221; and &#8220;Grammar&#8221;, 
 
133
and several dozen smaller libraries have also been written. 
 
134
Sometimes, though, what you want to do is &#8220;include all of this 
 
135
library file except for the definition of <code>SomeRoutine</code>&#8221;. 
 
136
You can do this by declaring:</p>
 
137
 
 
138
<p class="lynxonly"></p>
 
139
<pre class="code">Replace SomeRoutine;</pre>
 
140
 
 
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 &#8220;replace&#8221;.</p>
 
144
 
 
145
<p class="aside"><span class="warning">&#9650;&#9650;</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>
 
150
 
 
151
<p class="lynxonly"></p>
 
152
<pre class="code">System_file;</pre>
 
153
 
 
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>
 
159
 
 
160
<p class="dotbreak">� � � � �</p>
 
161
 
 
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 
 
164
as it compiles:</p>
 
165
 
 
166
<p class="lynxonly"></p>
 
167
<pre class="code">
 
168
Message &quot;An informational message&quot;;
 
169
Message error &quot;An error message&quot;;
 
170
Message fatalerror &quot;A fatal error message&quot;;
 
171
Message warning &quot;A warning message&quot;;
 
172
</pre>
 
173
 
 
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">&#167;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 &#8220;system file&#8221; (one that you have marked with a 
 
181
<code>System_file</code> directive). Informational messages are
 
182
simply printed:</p>
 
183
 
 
184
<p class="lynxonly"></p>
 
185
<pre class="code">Message &quot;Geometry library by Boris J. Parallelopiped&quot;;</pre>
 
186
 
 
187
<p class="normal">prints this text, followed by a new-line.</p>
 
188
 
 
189
<a id="p291" name="p291"></a>
 
190
<p class="aside"><span class="warning">&#9650;</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>
 
195
 
 
196
<p class="lynxonly"></p>
 
197
<pre class="code">
 
198
Ifndef VN_1610;
 
199
Message fatalerror
 
200
    &quot;The geometry extension needs Inform 6.1 or later&quot;;
 
201
Endif;
 
202
</pre>
 
203
 
 
204
<p class="aside">By special rule, the condition &#8220;<code>VN_1610</code> 
 
205
is defined&#8221; 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>
 
213
 
 
214
<p class="dotbreak">� � � � �</p>
 
215
 
 
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>
 
224
 
 
225
<p class="indent">The pieces of pre-compiled story file are called &#8220;modules&#8221; 
 
226
and they cannot be interpreted or used for anything other than linking.</p>
 
227
 
 
228
<p class="indent">The process is as follows. A game being compiled (called 
 
229
the &#8220;external&#8221; program) may <code>Link</code> one or more 
 
230
pre-compiled sections of code called &#8220;modules&#8221;. Suppose 
 
231
the game Jekyll has a subsection called Hyde. Then these two methods 
 
232
of making Jekyll are, very nearly, equivalent:</p>
 
233
 
 
234
<ol style="list-style-type:decimal">
 
235
<li>Putting <code>Include &quot;Hyde&quot;;</code> in the source for 
 
236
<tt>&quot;Jekyll&quot;</tt>, and compiling <tt>&quot;Jekyll&quot;</tt>.</li>
 
237
<li>Compiling <tt>&quot;Hyde&quot;</tt> with the <tt>-M</tt> 
 
238
(&#8220;module&#8221;) switch set, then putting <code>Link &quot;Hyde&quot;;</code> 
 
239
into the same point in the source for <tt>&quot;Jekyll&quot;</tt>, and 
 
240
compiling <tt>&quot;Jekyll&quot;</tt>.</li>
 
241
</ol>
 
242
 
 
243
<p class="normal">Option (2) is faster as long as <tt>&quot;Hyde&quot;</tt> 
 
244
does not change very often, since its ready-compiled module can be 
 
245
left lying around while <tt>&quot;Jekyll&quot;</tt> is being developed.</p>
 
246
 
 
247
<p class="indent">Because &#8220;linking the library&#8221; 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>
 
252
 
 
253
<p class="lynxonly"></p>
 
254
<pre class="code">Constant USE_MODULES;</pre>
 
255
 
 
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>
 
258
 
 
259
<p class="lynxonly"></p>
 
260
<pre class="code">
 
261
inform -M library/parserm.h
 
262
inform -M library/verblibm.h
 
263
</pre>
 
264
 
 
265
<p class="normal">where <tt>library/parserm.h</tt> should be replaced with 
 
266
whatever filename you keep the library file &#8220;<tt>parserm</tt>&#8221; 
 
267
in, and likewise for &#8220;<tt>verblibm</tt>&#8221;. This sounds
 
268
good, but here are four caveats:</p>
 
269
 
 
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
&quot;Parser&quot;</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 
 
285
the library.</li>
 
286
</ol>
 
287
 
 
288
<p class="aside"><span class="warning">&#9650;&#9650;</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>
 
293
 
 
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>&quot;linklpa.h&quot;</tt> 
 
298
(&#8220;link library properties and attributes&#8221;) 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 &#8220;fake actions&#8221;.</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>&quot;linklv.h&quot;</tt> (&#8220;link library variables&#8221;) 
 
312
imports all the library variables, so it would be sensible to include 
 
313
this.</li>
 
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>
 
325
</ol>
 
326
 
 
327
<p class="aside">These restrictions are mild in practice. As an example, 
 
328
here is a short module to play with:</p>
 
329
 
 
330
<p class="lynxonly"></p>
 
331
<pre class="code">
 
332
Include &quot;linklpa&quot;;        ! Make use of the properties, attributes
 
333
Include &quot;linklv&quot;;         ! and variables from the Library
 
334
[ LitThings x;
 
335
  objectloop (x has light)
 
336
      print (The) x, &quot; is currently giving off light.^&quot;;
 
337
];
 
338
</pre>
 
339
 
 
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>
 
343
 
 
344
<p class="dotbreak">� � � � �</p>
 
345
 
 
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 &#8220;banner&#8221;. For instance, a game compiled 
 
349
in December 1998 might have the banner line:</p>
 
350
 
 
351
<p class="output">Release 1 / Serial number 981218 / Inform v6.20 Library 6/8</p>
 
352
 
 
353
<p class="normal">The release number is 1 unless otherwise specified with the directive</p>
 
354
 
 
355
<p class="lynxonly"></p>
 
356
<pre class="code">Release &lt;number&gt;;</pre>
 
357
 
 
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,&#8230; to be amended re-releases.</p>
 
361
 
 
362
<p class="indent">The serial number is set automatically to the date 
 
363
of compilation in the form &#8220;yymmdd&#8221;, so that <code>981218</code> means 
 
364
&#8220;18th December 1998&#8221; and <code>000101</code> means 
 
365
&#8220;1st January 2000&#8221;. You can fix the date differently by setting</p>
 
366
 
 
367
<p class="lynxonly"></p>
 
368
<pre class="code">Serial &quot;dddddd&quot;;</pre>
 
369
 
 
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>
 
374
 
 
375
<a id="p294" name="p294"></a>
 
376
<p class="aside"><span class="warning">&#9650;</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>
 
380
 
 
381
</div>
 
382
<p class="navbar">
 
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="&#167;39: Controlling compilation from without">next</a> /
 
388
 <a href="dm4index.html">index</a>
 
389
</p>
 
390
</body>
 
391
</html>
 
392