mirror of
https://github.com/DrBeef/Raze.git
synced 2024-11-16 01:11:28 +00:00
Lunatic: various unrelated changes and more documentation.
- check map-text version on load - LunaCON: don't allow (back)slash as identifier char - LunaCON stand-alone: don't resort to default directory for root file names - document non-local control flow functions and for LunaCON, ambigious lexical elements git-svn-id: https://svn.eduke32.com/eduke32@3933 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
parent
6e443944c3
commit
f37d845f02
4 changed files with 99 additions and 14 deletions
|
@ -4,7 +4,7 @@ Helixhorned <contact: Duke4.net forums>
|
|||
:max-width: 56em
|
||||
:numbered:
|
||||
:icons:
|
||||
|
||||
:conf-files: lunatic.conf
|
||||
|
||||
|
||||
Introduction
|
||||
|
@ -204,3 +204,50 @@ Currently, the only exception to this rule is that a `definequote` is allowed
|
|||
inside delimited blocks, which however does not change its semantics in any
|
||||
way: it still only defines the initial contents of a quote, and does not
|
||||
magically act like `redefinequote`.
|
||||
|
||||
Ambiguous lexical elements
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
LunaCON is fairly relaxed as to which character sequences constitute valid
|
||||
identifier names used for e.g. ++define++d labels or variables. It does so out
|
||||
of the necessity of supporting CON code found ``in the wild''. An identifier
|
||||
|
||||
* must not be a token denoting a number,
|
||||
* must start with an _allowed first character_,
|
||||
* may contain any number of _allowed following characters_,
|
||||
|
||||
where
|
||||
|
||||
* allowed first characters are: letters, digits, and those in ```_*?`''
|
||||
* allowed following characters are the same as allowed first characters, plus
|
||||
``+++++'' and ``++-++'' .
|
||||
|
||||
// ^ `+` and `-`
|
||||
|
||||
Numbers can be written in either decimal or hexadecimal form, optionally
|
||||
prepended by a ``++-++'' sign. In the decimal case, the modulus of the number
|
||||
can be (lexically) any sequence of decimal digits, though there are
|
||||
restrictions on the permitted values.footnote:[Specifically, it is forbidden to
|
||||
write a number whose value falls outside the range [--2^31^-1 .. 2^32^--1\].]
|
||||
Hexadecimal number literals must be prefixed with `0x` or `0X`, and may
|
||||
optionally be suffixed with an `h`.
|
||||
|
||||
The following constructions are not allowed, as they would create ambiguities
|
||||
with the definitions above:
|
||||
|
||||
* A sequence of digits followed by letters to mean the the digits interpreted
|
||||
as a number, ignoring the trailing letters, e.g. `1267AT`.
|
||||
* A hexadecimal constant denoted using only a trailing `h`, for example
|
||||
`00000000h`.
|
||||
|
||||
Run-time changes
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
Behavior on error
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
As LunaCON is implemented by translating all given CON code to a Lunatic
|
||||
module, it is the Lunatic runtime that checks for proper use of its services at
|
||||
execution time and takes care of error handling and reporting. In Lua, an error
|
||||
link:lunatic.html/#nlcf[transfers control] to the end of the innermost
|
||||
``protected'' call of a Lua chunk.
|
||||
|
|
|
@ -1076,6 +1076,8 @@ containing the appropriate data.
|
|||
[[gameactor]]
|
||||
===== The function `gameactor{tilenum [, ...], func}`
|
||||
|
||||
:Lua51_FunctionCalls: http://www.lua.org/manual/5.1/manual.html#2.5.8
|
||||
|
||||
Registers custom code for the actor given by tile number `tilenum`. For each
|
||||
non-sleeping actor, the function `func` is called every game tic with three
|
||||
input arguments: `func(aci, pli, dist)`.
|
||||
|
@ -1098,6 +1100,7 @@ keys of the argument table. Each such input argument may be provided in at most
|
|||
one of these two forms. Furthermore, `func` may be provided as value to the
|
||||
key `'func'` as well.
|
||||
|
||||
[[gameactor_flags]]
|
||||
`[2] flags`::
|
||||
A number that controls both certain aspects of the `gameactor` call as well as
|
||||
the run-time behavior of the actor itself. A couple of bits for the latter type
|
||||
|
@ -1114,6 +1117,11 @@ actor (this may have happened from a CON `useractor` block, which gets
|
|||
translated to `gameactor`). Moreover, this mechanism allows to add run-time
|
||||
flags to the actor in question.
|
||||
+
|
||||
Chaining two callback functions is achieved by creating a new one that calls
|
||||
the first one, followed by a {Lua51_FunctionCalls}[tail call] of the second
|
||||
one. This has certain implications if control is transferred non-locally by
|
||||
e.g. using <<nlcf,`con.longjmp`>>.
|
||||
+
|
||||
Several flags in `AF` are provided to control how a `gameactor` invocation
|
||||
handles chaining.
|
||||
+
|
||||
|
@ -1383,8 +1391,8 @@ The `con` module -- game control
|
|||
|
||||
The `con` module on one hand provides functionality to control certain aspects
|
||||
of the game, such as defining game-side animations for actors. On the other
|
||||
hand, it hosts varioius functions that are familiar from CON, although
|
||||
sometimes under a different name.
|
||||
hand, it hosts various functions that are familiar from CON, although sometimes
|
||||
under a different name.
|
||||
|
||||
[[actions_moves_ais]]
|
||||
Actions, moves and AIs -- customizing actor behavior
|
||||
|
@ -1502,3 +1510,27 @@ an _AI_ object containing these. Also, it is called with three positional,
|
|||
optional arguments. Like for <<gameactor,`gameactor`>>, the numbers 0 and 1 are
|
||||
permissible for `action` and `move`. Applicable bits for `movflags` are
|
||||
available in the <<actor_MOVFLAGS,`actor.MOVFLAGS`>> object.
|
||||
|
||||
[[nlcf]]
|
||||
Non-local control flow
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Two functions in the `con` module make the executed function abort early,
|
||||
jumping directly to the end of the innermost event or actor callback
|
||||
``block''. They are used to implement among others CON's `killit` and
|
||||
(confusingly named) `return` commands. If these functions are used outside of
|
||||
the mentioned callback functions, the behavior is undefined.
|
||||
|
||||
`con.longjmp()`::
|
||||
Silently transfers control to the end of the innermost actor or event callback
|
||||
block, to the same point an `error()` call would do. Note that since callback
|
||||
<<gameactor_flags,chaining>> is achieved by creating a new function for each
|
||||
pair calling the original ones unprotected, issuing a `con.longjmp()` inside
|
||||
any ``part'' of a chain aborts the whole block -- functions in the chain that
|
||||
are called later will not be reached. In contrast, returning from one function
|
||||
transfers control to the beginning of the next in the chain if it exists.
|
||||
|
||||
`con.killit()`::
|
||||
Silently transfers control to the end of the active actor callback block,
|
||||
notifying the game to delete the executing actor's sprite. If `con.killit` is
|
||||
called while no execution of actor code is active, the behavior is undefined.
|
||||
|
|
|
@ -428,17 +428,21 @@ local function loadboard_maptext(fil, posptr, angptr, cursectnumptr)
|
|||
return RETERR-5
|
||||
end
|
||||
|
||||
if (not (map.version <= 10)) then
|
||||
return RETERR-6
|
||||
end
|
||||
|
||||
local msector, mwall, msprite = map.sector, map.wall, map.sprite
|
||||
|
||||
if (not alltabtab(msector) or not alltabtab(mwall) or not alltabtab(msprite)) then
|
||||
return RETERR-6
|
||||
return RETERR-7
|
||||
end
|
||||
|
||||
if (not tabofnumtabs(msector, sector_members) or
|
||||
not tabofnumtabs(mwall, wall_members) or
|
||||
not tabofnumtabs(msprite, sprite_members))
|
||||
then
|
||||
return RETERR-7
|
||||
return RETERR-8
|
||||
end
|
||||
|
||||
local numsectors, numwalls, numsprites = #msector, #mwall, #msprite
|
||||
|
@ -447,7 +451,7 @@ local function loadboard_maptext(fil, posptr, angptr, cursectnumptr)
|
|||
if (numsectors+0ULL > ffiC.MAXSECTORS or numwalls+0ULL > ffiC.MAXWALLS or
|
||||
numsprites+0ULL > ffiC.MAXSPRITES)
|
||||
then
|
||||
return RETERR-8
|
||||
return RETERR-9
|
||||
end
|
||||
|
||||
--- From here on, start filling out C structures. ---
|
||||
|
@ -466,21 +470,21 @@ local function loadboard_maptext(fil, posptr, angptr, cursectnumptr)
|
|||
-- Sectors.
|
||||
for i=0,numsectors-1 do
|
||||
if (read_struct(sector[i], msector[i+1], sector_members, sector_default)) then
|
||||
return RETERR-9
|
||||
return RETERR-10
|
||||
end
|
||||
end
|
||||
|
||||
-- Walls.
|
||||
for i=0,numwalls-1 do
|
||||
if (read_struct(wall[i], mwall[i+1], wall_members, wall_default)) then
|
||||
return RETERR-10
|
||||
return RETERR-11
|
||||
end
|
||||
end
|
||||
|
||||
-- Sprites.
|
||||
for i=0,numsprites-1 do
|
||||
if (read_struct(sprite[i], msprite[i+1], sprite_members, sprite_default)) then
|
||||
return RETERR-11
|
||||
return RETERR-12
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -500,12 +504,12 @@ local function loadboard_maptext(fil, posptr, angptr, cursectnumptr)
|
|||
|
||||
-- .point2 in {0, 1} --> wall index, sector[].wallptr/.wallnum
|
||||
if (restore_point2(true)) then
|
||||
return RETERR-12
|
||||
return RETERR-13
|
||||
end
|
||||
|
||||
-- Check .point2 at least.
|
||||
if (check_bad_point2()) then
|
||||
return RETERR-13
|
||||
return RETERR-14
|
||||
end
|
||||
|
||||
-- wall[]: .nextsector calculated by using engine's sectorofwall_noquick()
|
||||
|
|
|
@ -432,8 +432,10 @@ function on.actor_end(pos, usertype, tsamm, codetab)
|
|||
g_code.actor[tilenum] = codetab
|
||||
end
|
||||
|
||||
local BAD_ID_CHARS0 = "_/\\*?" -- allowed 1st identifier chars
|
||||
local BAD_ID_CHARS1 = "_/\\*-+?" -- allowed following identifier chars
|
||||
-- NOTE: in C-CON, the slash and backslash can also be part of an identifier,
|
||||
-- but this is likely to support file names in other places.
|
||||
local BAD_ID_CHARS0 = "_*?" -- allowed 1st identifier chars
|
||||
local BAD_ID_CHARS1 = "_*-+?" -- allowed following identifier chars
|
||||
|
||||
local function truetab(tab)
|
||||
local ttab = {}
|
||||
|
@ -879,7 +881,7 @@ local function do_include_file(dirname, filename, isroot)
|
|||
end
|
||||
|
||||
-- As a last resort, try the "default directory"
|
||||
if (fd==nil and g_defaultDir) then
|
||||
if (fd==nil and not isroot and g_defaultDir) then
|
||||
-- strip up to and including last slash (if any):
|
||||
filename = filename:gsub("^.*/", "")
|
||||
dirname = g_defaultDir.."/"
|
||||
|
|
Loading…
Reference in a new issue