mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-12-24 10:40:46 +00:00
Lunatic translator: ai/move/action.
This exposes some problems in the default/in-the-wild CONs. As usual, we'll have to retrofit sensible semantics :rolleyes:. git-svn-id: https://svn.eduke32.com/eduke32@2765 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
parent
23e43886a8
commit
cbb71c088a
1 changed files with 160 additions and 62 deletions
|
@ -91,29 +91,33 @@ local function parse_number(numstr)
|
|||
end
|
||||
|
||||
|
||||
local LABEL_DEFINE = 1
|
||||
--local LABEL_STATE = 2
|
||||
--local LABEL_ACTOR = 4
|
||||
local LABEL_ACTION = 8
|
||||
local LABEL_AI = 16
|
||||
local LABEL_MOVE = 32
|
||||
local LABEL = { MOVE=2, AI=3, ACTION=5, [2]="move", [3]="ai", [5]="action" }
|
||||
|
||||
local MOVE_NO_ = {0,0}
|
||||
local ACTION_NO_ = {0,0,0,0,0}
|
||||
local LABEL_NO = { [2]=MOVE_NO_, [3]={ACTION_NO_,MOVE_NO_,0}, [5]=ACTION_NO_ }
|
||||
|
||||
-- will contain:
|
||||
-- * scalar numbers: `define'd values
|
||||
-- * tables of length 2, 3, 5: move, ai, action definitions (respectively)
|
||||
-- - move: { hvel <num>, vvel <num> }
|
||||
-- - ai: { action <label str>, move <label str, or scalar 0 or 1>, flags <num> }
|
||||
-- - action: { startframe, numframes, viewtype, incval, delay } (all <num>)
|
||||
local g_labeldef = {}
|
||||
local g_labeltype = {}
|
||||
|
||||
local function reset_labels()
|
||||
g_labeldef = { NO=0 }
|
||||
g_labeltype = { NO=LABEL_DEFINE+LABEL_ACTION+LABEL_AI+LABEL_MOVE }
|
||||
g_labeldef = { NO=0 } -- NO is also a valid `move', `ai' or `action'
|
||||
|
||||
for i=1,#con.labels do
|
||||
for label, val in pairs(con.labels[i]) do
|
||||
g_labeldef[label] = val
|
||||
g_labeltype[label] = LABEL_DEFINE
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function lookup_defined_label(identifier)
|
||||
-- XXX: error reports give wrong numbers if e.g. happened in "actor" def
|
||||
-- (since it runs when fully parsed, i.e. at "enda")
|
||||
local function lookup_defined_label(maybe_minus_str, identifier)
|
||||
local num = g_labeldef[identifier]
|
||||
|
||||
if (num == nil) then
|
||||
|
@ -121,29 +125,28 @@ local function lookup_defined_label(identifier)
|
|||
return -inf -- return a number for type cleanness
|
||||
end
|
||||
|
||||
return num
|
||||
if (type(num) ~= "number") then
|
||||
errprintf("label \"%s\" is not a `define'd value", identifier)
|
||||
return -inf
|
||||
end
|
||||
|
||||
local function do_define_label(identifier, idornum)
|
||||
-- TODO: label types
|
||||
local num
|
||||
return (maybe_minus_str=="" and 1 or -1) * num
|
||||
end
|
||||
|
||||
if (type(idornum)=="number") then
|
||||
num = idornum
|
||||
else
|
||||
assert(idornum ~= nil)
|
||||
num = lookup_defined_label(idornum)
|
||||
if (num == -inf) then
|
||||
local function do_define_label(identifier, num)
|
||||
local oldval = g_labeldef[identifier]
|
||||
|
||||
if (oldval) then
|
||||
if (type(oldval) == "table") then
|
||||
errprintf("refusing to overwrite `%s' label \"%s\" with a `define'd value",
|
||||
LABEL[#oldval], identifier)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local oldnum = g_labeldef[identifier]
|
||||
if (oldnum) then
|
||||
-- con.labels[...]: don't warn for wrong PROJ_ redefinitions
|
||||
if (oldnum ~= num and con.labels[2][identifier]==nil) then
|
||||
if (oldval ~= num and con.labels[2][identifier]==nil) then
|
||||
warnprintf("label \"%s\" not redefined with new value %d (old: %d)",
|
||||
identifier, num, oldnum)
|
||||
identifier, num, oldval)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
@ -151,6 +154,82 @@ local function do_define_label(identifier, idornum)
|
|||
g_labeldef[identifier] = num
|
||||
end
|
||||
|
||||
local function check_move_literal(num)
|
||||
if (num~=0 and num~=1) then
|
||||
errprintf("literal `move' number must be either 0 or 1")
|
||||
return MOVE_NO_
|
||||
end
|
||||
|
||||
-- Both move 0 and 1 have hvel and vvel 0, but they must not compare equal
|
||||
-- for 'ifmove'. 0.1 will be truncated to 0 when passing to the game.
|
||||
-- XXX: this is still wrong, we need an ID
|
||||
return {0.1*num, 0.1*num}
|
||||
end
|
||||
|
||||
local function check_action_or_ai_literal(labeltype, num)
|
||||
if (num~=0) then
|
||||
errprintf("literal `%s' number must be 0", LABEL[labeltype])
|
||||
return LABEL_NO[labeltype]
|
||||
end
|
||||
|
||||
return LABEL_NO[labeltype]
|
||||
end
|
||||
|
||||
local function lookup_composite(labeltype, identifier)
|
||||
if (identifier=="NO") then
|
||||
-- NO is a special case and is valid for move, ai, action
|
||||
return LABEL_NO[labeltype]
|
||||
end
|
||||
|
||||
local val = g_labeldef[identifier]
|
||||
|
||||
if (val == nil) then
|
||||
errprintf("label \"%s\" is not defined", identifier)
|
||||
return LABEL_NO[labeltype] -- return a value of the expected type for cleanness
|
||||
end
|
||||
|
||||
if (type(val)~="table" or #val~=labeltype) then
|
||||
errprintf("label \"%s\" is not a%s `%s' value", identifier,
|
||||
labeltype==LABEL.MOVE and "" or "n", LABEL[labeltype])
|
||||
return LABEL_NO[labeltype]
|
||||
end
|
||||
|
||||
return val
|
||||
end
|
||||
|
||||
local function do_define_composite(labeltype, identifier, ...)
|
||||
local oldval = g_labeldef[identifier]
|
||||
|
||||
if (oldval) then
|
||||
if (type(oldval) ~= "table" or #val~=labeltype) then
|
||||
errprintf("refusing to overwrite `%s' label \"%s\" with a `%s' value",
|
||||
type(oldval)=="number" and "define" or LABEL[#oldval],
|
||||
identifier, LABEL[labeltype])
|
||||
return
|
||||
end
|
||||
|
||||
warnprintf("duplicate `%s' definition of \"%s\" ignored",
|
||||
LABEL[labeltype], identifier)
|
||||
return
|
||||
end
|
||||
|
||||
local val = {...}
|
||||
for i=#val+1,labeltype do
|
||||
val[i] = LABEL_NO[labeltype][i]
|
||||
end
|
||||
|
||||
if (labeltype == LABEL.AI) then
|
||||
-- OR together the flags
|
||||
for i=#val,LABEL.AI+1, -1 do
|
||||
val[LABEL.AI] = bit.bor(val[LABEL.AI], val[i])
|
||||
val[i] = nil
|
||||
end
|
||||
end
|
||||
|
||||
g_labeldef[identifier] = val
|
||||
end
|
||||
|
||||
|
||||
local function parse(contents) end -- fwd-decl
|
||||
|
||||
local function do_include_file(dirname, filename) end
|
||||
|
@ -169,26 +248,27 @@ else
|
|||
fd, msg = io.open(dirname..filename)
|
||||
|
||||
if (fd == nil) then
|
||||
printf("Fatal error: couldn't open %s", msg)
|
||||
printf("[%d] Fatal error: couldn't open %s", g_recurslevel, msg)
|
||||
g_numerrors = inf
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
printf("%s[%d] Parsing file \"%s\"", (g_recurslevel==-1 and "\n---- ") or "",
|
||||
g_recurslevel+1, dirname..filename);
|
||||
|
||||
local contents = fd:read("*all")
|
||||
fd:close()
|
||||
|
||||
if (contents == nil) then
|
||||
-- maybe that file name turned out to be a directory or other
|
||||
-- special file accidentally
|
||||
printf("Fatal error: couldn't read from \"%s\"", dirname..filename)
|
||||
printf("[%d] Fatal error: couldn't read from \"%s\"",
|
||||
g_recurslevel, dirname..filename)
|
||||
g_numerrors = inf
|
||||
return
|
||||
end
|
||||
|
||||
printf("%s[%d] Parsing file \"%s\"", (g_recurslevel==-1 and "\n---- ") or "",
|
||||
g_recurslevel+1, dirname..filename);
|
||||
|
||||
local oldfilename = g_filename
|
||||
g_filename = filename
|
||||
parse(contents)
|
||||
|
@ -347,6 +427,9 @@ local t_identifier = Var("t_identifier")
|
|||
-- This one matches keywords, too:
|
||||
local t_identifier_all = Var("t_identifier_all")
|
||||
local t_define = Var("t_define")
|
||||
local t_move = Var("t_move")
|
||||
local t_ai = Var("t_ai")
|
||||
local t_action = Var("t_action")
|
||||
-- NOTE: no chance to whitespace and double quotes in filenames:
|
||||
local t_filename = lpeg.C((anychar-Set(" \t\r\n\""))^1)
|
||||
local t_newline_term_str = match_until(anychar, newline)
|
||||
|
@ -379,7 +462,9 @@ local function n_defines(n) -- works well only for small n
|
|||
end
|
||||
|
||||
|
||||
local D, R, W, I = -1, -2, -3, -4;
|
||||
local D, R, W, I, AC, MV, AI = -1, -2, -3, -4, -5, -6, -7
|
||||
local TOKEN_PATTERN = { [D]=t_define, [R]=t_rvar, [W]=t_wvar, [I]=t_identifier,
|
||||
[AC]=t_action, [MV]=t_move, [AI]=t_ai }
|
||||
|
||||
-- Generic command pattern, types given by varargs.
|
||||
-- The command name to be matched is attached later.
|
||||
|
@ -393,18 +478,7 @@ local function cmd(...)
|
|||
local vartypes = {...}
|
||||
|
||||
for i=1,#vartypes do
|
||||
assert(vartypes[i] < 0)
|
||||
|
||||
if (vartypes[i] == D) then
|
||||
pat = pat * sp1 * t_define
|
||||
elseif (vartypes[i] == R) then
|
||||
pat = pat * sp1 * t_rvar
|
||||
elseif (vartypes[i] == W) then
|
||||
pat = pat * sp1 * t_wvar
|
||||
else -- I
|
||||
assert(vartypes[i] == I)
|
||||
pat = pat * sp1 * t_identifier
|
||||
end
|
||||
pat = pat * sp1 * assert(TOKEN_PATTERN[vartypes[i]])
|
||||
end
|
||||
|
||||
return pat
|
||||
|
@ -463,9 +537,18 @@ local Co = {
|
|||
gamearray = cmd(I,D),
|
||||
|
||||
--- 5. Top level commands that are also run-time commands
|
||||
action = sp1 * t_identifier * (sp1 * t_define)^-5 / function(id) do_define_label(id, 0) end, -- TEMP
|
||||
ai = sp1 * t_identifier * (sp1 * t_define)^0 / function(id) do_define_label(id, 0) end, -- TEMP
|
||||
move = sp1 * t_identifier * (sp1 * t_define)^-2 / function(id) do_define_label(id, 0) end, -- TEMP
|
||||
-- startframe, numframes, viewtype, incval, delay:
|
||||
action = sp1 * t_identifier * (sp1 * t_define)^-5 /
|
||||
function(...) do_define_composite(LABEL.ACTION, ...) end,
|
||||
|
||||
-- action, move, flags...:
|
||||
ai = sp1 * t_identifier * (sp1 * t_action *
|
||||
(sp1 * t_move * (sp1 * t_define)^0)^-1
|
||||
)^-1 /
|
||||
function(...) do_define_composite(LABEL.AI, ...) end,
|
||||
|
||||
move = sp1 * t_identifier * (sp1 * t_define)^-2 / -- hvel, vvel
|
||||
function(...) do_define_composite(LABEL.MOVE, ...) end,
|
||||
|
||||
--- 6. Deprecated TLCs
|
||||
betaname = newline_term_string,
|
||||
|
@ -593,9 +676,9 @@ local Ci = {
|
|||
--- 3. Actors
|
||||
-- These three need more attention (different kind of labels; move
|
||||
-- additionally may accept 0 or 1):
|
||||
action = cmd(D),
|
||||
ai = cmd(D),
|
||||
move = sp1 * t_define * (sp1 * t_define)^0,
|
||||
action = cmd(AC),
|
||||
ai = cmd(AI),
|
||||
move = sp1 * t_move * (sp1 * t_define)^0,
|
||||
|
||||
cactor = cmd(D),
|
||||
count = cmd(D),
|
||||
|
@ -829,9 +912,9 @@ local Ci = {
|
|||
|
||||
local Cif = {
|
||||
-- XXX: ai, action, move/def labels
|
||||
ifai = cmd(D),
|
||||
ifaction = cmd(D),
|
||||
ifmove = cmd(D),
|
||||
ifai = cmd(AI),
|
||||
ifaction = cmd(AC),
|
||||
ifmove = cmd(MV),
|
||||
|
||||
ifrnd = cmd(D),
|
||||
ifpdistl = cmd(D),
|
||||
|
@ -1066,15 +1149,23 @@ local stmt_list = Var("stmt_list")
|
|||
local stmt_list_or_eps = (stmt_list * sp1)^-1
|
||||
local stmt_list_nosp_or_eps = (stmt_list * (sp1 * stmt_list)^0)^-1
|
||||
|
||||
-- common to all three: <name/tilenum> [<strength> [<action> [<move> [<ai>... ]]]]
|
||||
local common_actor_end = sp1 * t_define * sp1 * (t_define * sp1)^0 * stmt_list_or_eps * "enda"
|
||||
-- common to actor and useractor: <name/tilenum> [<strength> [<action> [<move> [<flags>... ]]]]
|
||||
local common_actor_end = sp1 * t_define *
|
||||
(sp1 * t_define *
|
||||
(sp1 * t_action *
|
||||
(sp1 * t_move *
|
||||
(sp1 * t_define)^0
|
||||
)^-1
|
||||
)^-1
|
||||
)^-1
|
||||
* sp1 * stmt_list_or_eps * "enda"
|
||||
|
||||
--== block delimiters (no recursion) ==--
|
||||
local Cb = {
|
||||
-- actor (...)
|
||||
actor = common_actor_end,
|
||||
-- eventloadactor (...)
|
||||
eventloadactor = common_actor_end,
|
||||
-- eventloadactor <name/tilenum>
|
||||
eventloadactor = sp1 * t_define * sp1 * stmt_list_or_eps * "enda",
|
||||
-- useractor <actortype> (...)
|
||||
useractor = sp1 * t_define * common_actor_end,
|
||||
|
||||
|
@ -1135,7 +1226,14 @@ local Grammar = Pat{
|
|||
-- getactor [THISACTOR].y y
|
||||
-- This is in need of cleanup!
|
||||
t_identifier = -NotKeyw(con.keyword * (sp1 + "[")) * lpeg.C(t_identifier_all),
|
||||
t_define = (t_maybe_minus * t_identifier/lookup_defined_label) + t_number, -- TODO: minus
|
||||
t_define = (lpeg.C(t_maybe_minus) * t_identifier / lookup_defined_label) + t_number,
|
||||
|
||||
t_move = (t_identifier/function(id) lookup_composite(LABEL.MOVE, id) end) +
|
||||
t_number/check_move_literal,
|
||||
t_ai = (t_identifier/function(id) lookup_composite(LABEL.AI, id) end) +
|
||||
t_number/function(num) check_action_or_ai_literal(LABEL.AI, num) end,
|
||||
t_action = (t_identifier/function(id) lookup_composite(LABEL.ACTION, id) end) +
|
||||
t_number/function(num) check_action_or_ai_literal(LABEL.ACTION, num) end,
|
||||
|
||||
t_arrayexp = t_identifier * arraypat * memberpat^-1,
|
||||
|
||||
|
|
Loading…
Reference in a new issue