diff --git a/polymer/eduke32/source/lunatic/doc/lunacon.txt b/polymer/eduke32/source/lunatic/doc/lunacon.txt index 2a1e2b93c..1a692be92 100644 --- a/polymer/eduke32/source/lunatic/doc/lunacon.txt +++ b/polymer/eduke32/source/lunatic/doc/lunacon.txt @@ -4,7 +4,7 @@ Helixhorned :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. diff --git a/polymer/eduke32/source/lunatic/doc/lunatic.txt b/polymer/eduke32/source/lunatic/doc/lunatic.txt index ebf372647..f5ff32871 100644 --- a/polymer/eduke32/source/lunatic/doc/lunatic.txt +++ b/polymer/eduke32/source/lunatic/doc/lunatic.txt @@ -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 <>. ++ 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 <>, the numbers 0 and 1 are permissible for `action` and `move`. Applicable bits for `movflags` are available in the <> 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 +<> 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. diff --git a/polymer/eduke32/source/lunatic/engine_maptext.lua b/polymer/eduke32/source/lunatic/engine_maptext.lua index 507cbfff0..76a2a5ef5 100644 --- a/polymer/eduke32/source/lunatic/engine_maptext.lua +++ b/polymer/eduke32/source/lunatic/engine_maptext.lua @@ -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() diff --git a/polymer/eduke32/source/lunatic/lunacon.lua b/polymer/eduke32/source/lunatic/lunacon.lua index ed31bf2a0..13c48c932 100644 --- a/polymer/eduke32/source/lunatic/lunacon.lua +++ b/polymer/eduke32/source/lunatic/lunacon.lua @@ -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.."/"