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:
helixhorned 2013-07-07 20:58:57 +00:00
parent 6e443944c3
commit f37d845f02
4 changed files with 99 additions and 14 deletions

View file

@ -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.

View file

@ -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.

View file

@ -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()

View file

@ -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.."/"