Subversion Repositories eduke32

Rev

Rev 5008 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
3907 helixhorne 1
LunaCON User Manual -- The ``Lunatic Translator''
2
=================================================
3
Helixhorned <contact: Duke4.net forums>
4
:max-width: 56em
5
:numbered:
6
:icons:
4032 helixhorne 7
:toc:
3933 helixhorne 8
:conf-files: lunatic.conf
3907 helixhorne 9
 
10
 
11
Introduction
12
------------
13
 
14
The Lunatic build of EDuke32 completely reimplements the CON scripting language
15
using the framework provided by its Lua interface. It does so by generating at
16
start-up time one Lunatic module from all specified CON files and
17
mutators.footnote:[In CON, the *`include`* directive amounts to merely textual
18
inclusion, as is mutator appending with the `-mx` switch. All CON code is
19
translated in one global context sharing the same namespace.]
20
 
21
LunaCON implements nearly all of modern EDuke32 CON. One of its main aims is
22
correctness in a broad sense, which encompasses multiple issues.
23
 
24
* LunaCON more strictly validates the CON source at translation time. For
25
  example, using labels of mismatched type, such as a ++define++d number where
4814 helixhorne 26
  a `move` is expected, issues an translation error.
3907 helixhorne 27
 
28
* Lexically and syntactically, LunaCON accepts only a subset of what the C-CON
29
  translator would pass through. This includes rejecting clearly erroneous code
30
  such as an unfinished directive at the end of a translation unit, but also
31
  code that implies ambiguities in the language.
32
 
33
* On the run-time side, most checking is done by Lunatic. For example, indexing
34
  actor gamevars with out-of-bounds values produces an error that gets
35
  permanently displayed on the screen. Like with Lua code, the
4880 helixhorne 36
  link:lunatic.html#error[error] entry in the log then contains a traceback
3907 helixhorne 37
  annotated with line numbers, making it possible for the CON coder to pinpoint
38
  its location and context.
39
 
40
For these reasons, many existing CON mods and TCs are expected to need
41
amendments in order to translate and/or run properly. This is generally a
42
desired thing, since otherwise (most of the time, unintentional) misuse of the
43
CON system may produce behavior that is either erratic, or appears to work on
44
the surface but is hiding potential issues.
45
 
46
.A warning
47
The code generated by LunaCON is unsuitable for human consumption --
48
specifically, it should not be used as a base for new Lunatic code. Even though
49
that code runs in Lunatic's protected user environment, it uses private
50
interfaces that are subject to change in addition to the officially exposed and
51
documented ones.
52
 
53
Nevertheless, LunaCON is also available as a stand-alone Lua script. Primarily,
54
this allows it to be used as a checking tool during CON development without the
55
need to start EDuke32. Also, multiple CON codebases can be checked in a batch
56
fashion for non-runtime problems.
57
 
58
 
59
Usage
60
-----
61
:LuaJIT: http://luajit.org
62
:LPeg: http://www.inf.puc-rio.br/~roberto/lpeg/
63
 
64
The stand-alone LunaCON script, `lunacon.lua`, needs {LuaJIT}[LuaJIT] for
3956 helixhorne 65
execution and {LPeg}[LPeg] as additional dependency.footnote:[In order to
66
translate some very large CON files, minor modifications have to be made to
67
LuaJIT and LPeg. Refer to `lunatic/doc/how_to_build_lunatic.txt` in the EDuke32
3969 helixhorne 68
source distribution for details.] The script also requires `con_lang.lua` to be
69
present. It expects one or more names of root CON files together with any
70
number of options, in any order (arguments starting with a dash are always
71
interpreted as the latter).
3907 helixhorne 72
 
73
.Example usage
74
----------
75
luajit ./lunacon.lua -Wall mymod.con
76
----------
77
 
78
All arguments after a single `@` argument are taken to name _file lists_.
79
These are files containing lines either
80
 
81
* a file name of a root CON file which gets processed, or
82
* a completely blank line or a line starting with `#`, both of which are ignored.
83
 
84
 
85
Options
86
-------
87
 
88
Most options documented in the following can also be passed to the Lunatic
89
build of EDuke32. Options on the command line are processed in their given
90
order, from left to right. Many of them can be negated by appeding `no-` after
91
the ``option category letter'', for example `-Wno-not-redefined`. This index
92
only lists the positive forms of each non-compound option and labels whether it
93
is enabled or disabled by default.
94
 
95
General options
96
~~~~~~~~~~~~~~~
97
 
98
++-I__directory__++ (stand-alone only)::
99
Specifies a _default directory_ to search for CON files as a last resort. This
100
can be useful if mods expect part of their included files to reside inside GRP
101
or ZIP containers, which the stand-alone translator cannot examine. This option
102
can only be passed once.
103
 
104
Warning options
105
~~~~~~~~~~~~~~~
106
 
107
These options affect on which occasions warnings, or in some cases, errors
108
instead of warnings, are produced at translation time.
109
 
110
`-Wall`::
111
Enables all warning and errors described in this subsection.
112
 
113
`-Wbad-identifier` (default: off)::
114
Warns whenever an identifier does not match `[A-Za-z_][A-Za-z0-9_]*`. In words,
115
a ``good'' identifier is expected to start with a letter or an underscore,
116
followed by zero or more letters, underscores, or digits.
117
 
118
`-Wchained-loadactor` (default: on)::
119
Warns whenever an `eventloadactor` block appears multiple times for the same
120
tile number. In LunaCON, these are translated to an `EVENT_LOADACTOR` block
121
that checks the tile number of its current actor. This event gets chained to
122
the end of all preceding `EVENT_LOADACTOR` definitions, whereas with C-CON, a
123
new `eventloadactor` block for the same tile number would override the existing
124
one.
125
 
126
`-Werror-bad-getactorvar` (default: off)::
127
When enabled, produces an error whenever a global or per-player gamevar is
128
attempted to be read using ++getactorvar++. Otherwise, a warning is emitted. In
129
this case, the generated code is either a read of the (global) gamevar, or an
4266 helixhorne 130
access of the per-player gamevar with the given index or the current player
131
index (depending on `-fbad-getactorvar-use-pli`), which is probably not what
132
the coder intended.
3907 helixhorne 133
 
134
`-Wnot-redefined` (default: on)::
135
Warns whenever a `define` directive was ignored because it attempted to
136
redefine an already existing label to a different number. The label can exist
137
either due to a previous `define`, or because it is a predefined label such as
138
`NO`.
139
 
140
`-Wnumber-conversion` (default: on)::
141
Warns whenever a literal decimal number is encountered that is out of the range
142
for a 32-bit integer, but inside that of an unsigned 32-bit integer. In this
143
case, 2^32^ is subtracted from the number, producing a negative value without
144
changing the bit representation.
145
 
4299 helixhorne 146
`-Wnever-used-gamevar` (default: off)::
147
After translation, issues a warning for every CON-side user gamevar definition
148
that was never referenced, that is, neither read nor written in the CON code.
149
 
150
`-Wnever-read-gamevar` (default: off)::
151
After translation, issues a warning for every CON-side user gamevar definition
152
that was assigned to but never read in the CON code.
153
 
3907 helixhorne 154
`-Wsystem-gamevar` (default: on)::
155
Warns whenever the initial value of a system gamevar was overridden (by issuing
156
`gamevar` at file scope), but the provided gamevar flags did not match those of
157
the kept predefined ones.
158
 
159
Code generation options
160
~~~~~~~~~~~~~~~~~~~~~~~
161
 
162
These options change the way certain CON code constructs are translated to Lua,
163
set the output behavior of the stand-alone translator, or toggle various error
164
conditions.
165
 
166
`-fno` (stand-alone only)::
3969 helixhorne 167
Disable printing out the generated code and validating its syntax.
3907 helixhorne 168
 
169
`-fno=onlycheck` (stand-alone only)::
3969 helixhorne 170
Disable printing out the generated code, but validate whether it is
171
syntactically legal Lua code. A failure of this check represents a bug with
172
LunaCON itself.
3907 helixhorne 173
 
4860 helixhorne 174
`-fnames` (stand-alone only)::
175
Instead of generating Lua code, output all ++define++d names that were ever
176
passed as tile number to `actor`, `useractor` or `eventloadactor` in a form
177
suitable for the `names.h` file read by Mapster32.
178
 
3907 helixhorne 179
`-ferror-nostate` (default: on)::
180
If enabled, an attempt to call a `state` that was not previously defined
181
results in an error. Otherwise, a warning is issued and no code is generated
182
for the `state` invocation.
183
 
4290 helixhorne 184
`-ferror-nonlocal-userdef` (default: on)::
185
If enabled, an attept to issue `getuserdef` or `setuserdef` when the current
186
player doesn't equal the local player generates an error. Otherwise, the
4291 helixhorne 187
userdef structure can be accessed irrespective of the current player.
4290 helixhorne 188
 
4356 helixhorne 189
`-ferror-negative-tag-write` (default: off)::
190
If enabled, an attempt to assign a negative value to the `lotag` or `hitag`
191
member of the sector, wall or (t)sprite structures produces an error.
192
Normally, it is legal to assign negative values to these members, but since
193
they are unsigned 16-bit integers on the C side, such values will be converted
194
to positive ones and may entail undesired behavior.
195
+
196
NOTE: From CON as well as Lunatic, `hitag` and `lotag` are seen as *signed*
197
16-bit integers.
198
 
4962 helixhorne 199
`-fbad-getactorvar-use-pli` (default: on)::
4266 helixhorne 200
If enabled and `-Werror-bad-getactorvar` is off, a `getactorvar` of a
201
per-player variable will result the gamevar being indexed with the current
202
player instead of the provided index. This is the (probably unintended)
203
behavior of C-CON.
204
 
3907 helixhorne 205
`-fplayervar` (default: on)::
206
If enabled, per-player `gamevar` definitions really generate `con.playervar`
207
initializations in the translated Lua code. Otherwise, per-player gamevars are
208
treated as global gamevars, which can be useful for code that attempts to
209
access them in contexts with no current player, yielding errors in Lunatic.
210
 
3956 helixhorne 211
`-ftrapv` (default: off)::
212
Enable _trapping_ behavior for arithmetic operations whose result overflows the
213
range of a signed 32-bit integer, i.e. generate an error on overflow. By
214
default, overflow results in undefined behavior. Currently, only multiplication
215
is handled.
3907 helixhorne 216
 
3956 helixhorne 217
`-fwrapv` (default: off)::
218
Enable _wrapping_ behavior for arithmetic operations whose result overflows the
219
range of a signed 32-bit integer, i.e. after each operation, only the 32 lower
220
bits of the result are kept. Currently, only multiplication is handled. Only
221
one of `-ftrapv` or `-fwrapv` may be enabled at the same time.
222
 
223
 
3907 helixhorne 224
Differences from C-CON
225
----------------------
226
 
227
Despite the aim to provide as much compatibility to CON as possible where
228
reasonable, a couple of its ``features'' -- some of which are coincidental --
229
cannot be implemented without unnaturally bending the implementation into
230
shape. On the other hand, LunaCON sports some features that C-CON lacks, and
231
does not exhibit some of its strange quirks or outright bugs.
232
 
3956 helixhorne 233
 
3907 helixhorne 234
Syntactic and lexical changes
235
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
236
 
237
The two command classes
238
^^^^^^^^^^^^^^^^^^^^^^^
239
 
240
LunaCON makes a clear distinction between ``outer'' commands that have an
241
effect when translating a CON file (_directives_ such as `gamevar`,
242
`definesound` or `spritenvg`) and ``inner'' commands meant to be effective at
243
execution time of `actor`/`useractor`, `state`, `event` and `eventloadactor`
4151 helixhorne 244
blocks. Thus, issuing directives inside of these will make LunaCON reject the
3907 helixhorne 245
input file due to a syntax error, as will an attempt to use run-time commands
246
such as `sizeat` at file scope.
247
 
248
This strict behavior is one hand a consequence of how the LunaCON parser is
249
structured, but on the other hand it may expose code for which the author
250
misunderstood its meaning. An example for the first case would be a `gamevar`
251
inside a block, which one mistakenly could take to have local scope. Gamevars
252
in CON always have both global scope and lifetime though, so such a mental
253
model on the coder's part may lead to unexpected bugs. In the second case,
254
run-time commands at file scope are really translated to bytecode by C-CON, but
255
as they reside outside of any block, they are never reached -- in other words,
256
they are dead code.
257
 
258
Currently, the only exception to this rule is that a `definequote` is allowed
259
inside delimited blocks, which however does not change its semantics in any
260
way: it still only defines the initial contents of a quote, and does not
261
magically act like `redefinequote`.
3933 helixhorne 262
 
263
Ambiguous lexical elements
264
^^^^^^^^^^^^^^^^^^^^^^^^^^
265
 
266
LunaCON is fairly relaxed as to which character sequences constitute valid
267
identifier names used for e.g. ++define++d labels or variables. It does so out
268
of the necessity of supporting CON code found ``in the wild''. An identifier
269
 
270
* must not be a token denoting a number,
271
* must start with an _allowed first character_,
272
* may contain any number of _allowed following characters_,
273
 
274
where
275
 
276
* allowed first characters are: letters, digits, and those in ```_*?`''
277
* allowed following characters are the same as allowed first characters, plus
4473 helixhorne 278
  ``+++++'', ``++-++'' and ``++.++''.
3933 helixhorne 279
 
280
// ^ `+` and `-`
281
 
282
Numbers can be written in either decimal or hexadecimal form, optionally
283
prepended by a ``++-++'' sign. In the decimal case, the modulus of the number
284
can be (lexically) any sequence of decimal digits, though there are
285
restrictions on the permitted values.footnote:[Specifically, it is forbidden to
286
write a number whose value falls outside the range [--2^31^-1 .. 2^32^--1\].]
287
Hexadecimal number literals must be prefixed with `0x` or `0X`, and may
288
optionally be suffixed with an `h`.
289
 
290
The following constructions are not allowed, as they would create ambiguities
291
with the definitions above:
292
 
293
* A sequence of digits followed by letters to mean the the digits interpreted
294
  as a number, ignoring the trailing letters, e.g. `1267AT`.
295
* A hexadecimal constant denoted using only a trailing `h`, for example
296
  `00000000h`.
297
 
3956 helixhorne 298
Miscellaneous
299
^^^^^^^^^^^^^
300
 
301
* Read array expressions as well as `switch` statements can be arbitrarily
302
  nested.
303
 
304
// XXX: 'Read' is confusing. Need better wording.
305
 
306
 
3933 helixhorne 307
Run-time changes
308
~~~~~~~~~~~~~~~~
309
 
310
Behavior on error
311
^^^^^^^^^^^^^^^^^
312
 
313
As LunaCON is implemented by translating all given CON code to a Lunatic
314
module, it is the Lunatic runtime that checks for proper use of its services at
315
execution time and takes care of error handling and reporting. In Lua, an error
4880 helixhorne 316
link:lunatic.html#nlcf[transfers control] to the end of the innermost
3933 helixhorne 317
``protected'' call of a Lua chunk.
3942 helixhorne 318
 
319
This is in contrast to C-CON, which for some errors would print a message to
320
the log, but otherwise would continue execution as if nothing had happened. In
3956 helixhorne 321
LunaCON, the code following an error is *not* executed. This way, the author of
322
the CON code is notified of the presence of the bug, and by fixing it
323
eventually obtains cleaner code.
3942 helixhorne 324
 
3956 helixhorne 325
Quote behavior
326
^^^^^^^^^^^^^^
3942 helixhorne 327
 
3956 helixhorne 328
* The `redefinequote` command can be issued even if the given quote number has
329
  not been previously allocated using the `definequote` directive. This makes
4032 helixhorne 330
  it possible to use a range of quote numbers on the fly without the need to
331
  declare their future use.
3942 helixhorne 332
 
3956 helixhorne 333
Miscellaneous
334
^^^^^^^^^^^^^
335
 
336
* Issuing `break` inside a part of an event chain (defined using multiple
4104 helixhorne 337
  `onevent` blocks for one event kind) does not abort the whole chain.
3956 helixhorne 338
 
339
 
340
Unavailable functionality
341
~~~~~~~~~~~~~~~~~~~~~~~~~
342
 
343
C-CON's `jump` and `getcurraddress` are not available and will not be
344
implemented.
345
 
3942 helixhorne 346
The following commands are not yet implemented. Those highlighted in bold give
3956 helixhorne 347
errors, while the others merely warn either at translation or execution
4291 helixhorne 348
time.
3942 helixhorne 349
 
350
Directives
351
^^^^^^^^^^
4291 helixhorne 352
*`includedefault`*, `definecheat`, `setcfgname`, `setgamename`
3942 helixhorne 353
 
354
Run-time commands
355
^^^^^^^^^^^^^^^^^
356
 
5031 hendricks2 357
*`activatecheat`*, *`clearmapstate`*, *`startcutscene`*, *`ifcutscene`*, `save`,
5008 helixhorne 358
`savenn`, *`lineintersect`*, *`rayintersect`*, *`sectorofwall`*.
3942 helixhorne 359
 
3956 helixhorne 360
Additionally, various multiplayer-related commands either unconditionally
361
return results as if no multiplayer game is in progress, or are non-functional
362
for more than the first player. Also, some MP-related variables are merely
363
predefined constants.