mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-12-26 03:30:46 +00:00
Lunatic translator: prototypical array/struct access, for reference only.
git-svn-id: https://svn.eduke32.com/eduke32@3432 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
parent
79384f0e79
commit
faae812293
2 changed files with 154 additions and 37 deletions
|
@ -302,6 +302,75 @@ wdata_members =
|
||||||
"int32_t flashcolor",
|
"int32_t flashcolor",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ActorLabels =
|
||||||
|
{
|
||||||
|
x = "sprite[%s].x",
|
||||||
|
y = "sprite[%s].y",
|
||||||
|
z = "sprite[%s].z",
|
||||||
|
cstat = "sprite[%s].cstat",
|
||||||
|
picnum = "sprite[%s].picnum",
|
||||||
|
shade = "sprite[%s].shade",
|
||||||
|
pal = "sprite[%s].pal",
|
||||||
|
clipdist = "sprite[%s].clipdist",
|
||||||
|
-- filler = "sprite[%s].filler",
|
||||||
|
detail = "sprite[%s].filler",
|
||||||
|
xrepeat = "sprite[%s].xrepeat",
|
||||||
|
yrepeat = "sprite[%s].yrepeat",
|
||||||
|
xoffset = "sprite[%s].xoffset",
|
||||||
|
yoffset = "sprite[%s].yoffset",
|
||||||
|
sectnum = "sprite[%s].sectnum",
|
||||||
|
statnum = "sprite[%s].statnum",
|
||||||
|
ang = "sprite[%s].ang",
|
||||||
|
owner = "sprite[%s].owner",
|
||||||
|
xvel = "sprite[%s].xvel",
|
||||||
|
yvel = "sprite[%s].yvel",
|
||||||
|
zvel = "sprite[%s].zvel",
|
||||||
|
lotag = "sprite[%s].lotag",
|
||||||
|
hitag = "sprite[%s].hitag",
|
||||||
|
extra = "sprite[%s].extra",
|
||||||
|
|
||||||
|
-- { get, set }
|
||||||
|
-- Read access differs from write:
|
||||||
|
ulotag = { "(sprite[%s].lotag+65536)%65535", "sprite[%s].lotag" },
|
||||||
|
uhitag = { "(sprite[%s].hitag+65536)%65535", "sprite[%s].hitag" },
|
||||||
|
|
||||||
|
-- ActorExtra labels...
|
||||||
|
htcgg = "actor[%s].cgg",
|
||||||
|
htpicnum = "actor[%s].picnum",
|
||||||
|
htang = "actor[%s].ang",
|
||||||
|
htextra = "actor[%s].extra",
|
||||||
|
htowner = "actor[%s].owner",
|
||||||
|
htmovflag = "actor[%s].movflag",
|
||||||
|
httempang = "actor[%s].tempang",
|
||||||
|
htactorstayput = "actor[%s].actorstayput",
|
||||||
|
htdispicnum = "actor[%s].dispicnum",
|
||||||
|
httimetosleep = "actor[%s].timetosleep",
|
||||||
|
htfloorz = "actor[%s].floorz",
|
||||||
|
htceilingz = "actor[%s].ceilingz",
|
||||||
|
htlastvx = "actor[%s].lastvx",
|
||||||
|
htlastvy = "actor[%s].lastvy",
|
||||||
|
htbposx = "actor[%s].bpos.x",
|
||||||
|
htbposy = "actor[%s].bpos.y",
|
||||||
|
htbposz = "actor[%s].bpos.z",
|
||||||
|
-- Read access differs from write, write not available:
|
||||||
|
htg_t = { "actor[%s].get_t_data(%s)" },
|
||||||
|
htflags = "actor[%s].flags",
|
||||||
|
|
||||||
|
-- model flags
|
||||||
|
angoff = "spriteext[%s].angoff",
|
||||||
|
pitch = "spriteext[%s].pitch",
|
||||||
|
roll = "spriteext[%s].roll",
|
||||||
|
mdxoff = "spriteext[%s].xoff",
|
||||||
|
mdyoff = "spriteext[%s].yoff",
|
||||||
|
mdzoff = "spriteext[%s].zoff",
|
||||||
|
mdflags = "spriteext[%s].mdflags",
|
||||||
|
xpanning = "spriteext[%s].xpanning",
|
||||||
|
ypanning = "spriteext[%s].ypanning",
|
||||||
|
|
||||||
|
alpha = { "_math.floor(spriteext[%s].alpha*255)" },
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
-- NOTE: These MUST be in reverse lexicographical order!
|
-- NOTE: These MUST be in reverse lexicographical order!
|
||||||
-- Per CON syntax, valid identifiers names are disjunct from keywords,
|
-- Per CON syntax, valid identifiers names are disjunct from keywords,
|
||||||
-- so that a rule like
|
-- so that a rule like
|
||||||
|
|
|
@ -400,6 +400,7 @@ local function reset_labels()
|
||||||
COOP = 0,
|
COOP = 0,
|
||||||
MULTIMODE = 0,
|
MULTIMODE = 0,
|
||||||
numplayers = 1,
|
numplayers = 1,
|
||||||
|
myconnectindex = 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
for varname,_ in pairs(g_labeldef) do
|
for varname,_ in pairs(g_labeldef) do
|
||||||
|
@ -910,27 +911,24 @@ local tok =
|
||||||
maybe_minus = (Pat("-") * sp0)^-1,
|
maybe_minus = (Pat("-") * sp0)^-1,
|
||||||
number = Var("t_number"),
|
number = Var("t_number"),
|
||||||
|
|
||||||
-- Valid identifier names are disjunct from keywords!,
|
-- Valid identifier names are disjunct from keywords!
|
||||||
-- XXX: CON is more permissive with identifier name characters:,
|
-- XXX: CON is more permissive with identifier name characters:
|
||||||
identifier = Var("t_identifier"),
|
identifier = Var("t_identifier"),
|
||||||
-- This one matches keywords, too:,
|
-- This one matches keywords, too:
|
||||||
identifier_all = Var("t_identifier_all"),
|
identifier_all = Var("t_identifier_all"),
|
||||||
define = Var("t_define"),
|
define = Var("t_define"),
|
||||||
move = Var("t_move"),
|
move = Var("t_move"),
|
||||||
ai = Var("t_ai"),
|
ai = Var("t_ai"),
|
||||||
action = Var("t_action"),
|
action = Var("t_action"),
|
||||||
|
|
||||||
-- NOTE: no chance to whitespace and double quotes in filenames:,
|
-- NOTE: no chance to whitespace and double quotes in filenames:
|
||||||
filename = lpeg.C((anychar-Set(" \t\r\n\""))^1),
|
filename = lpeg.C((anychar-Set(" \t\r\n\""))^1),
|
||||||
newline_term_str = match_until(anychar, newline),
|
newline_term_str = match_until(anychar, newline),
|
||||||
|
|
||||||
-- new-style inline arrays and structures:,
|
|
||||||
arrayexp = Var("t_arrayexp"),
|
|
||||||
|
|
||||||
rvar = Var("t_rvar"),
|
rvar = Var("t_rvar"),
|
||||||
wvar = Var("t_wvar"),
|
wvar = Var("t_wvar"),
|
||||||
|
|
||||||
-- for definelevelname,
|
-- for definelevelname
|
||||||
time = lpeg.C(alphanum*alphanum^-1*":"*alphanum*alphanum^-1),
|
time = lpeg.C(alphanum*alphanum^-1*":"*alphanum*alphanum^-1),
|
||||||
|
|
||||||
state_ends = Pat("ends")
|
state_ends = Pat("ends")
|
||||||
|
@ -1076,32 +1074,74 @@ end
|
||||||
-- (if there ever were any) but making our life harder else.
|
-- (if there ever were any) but making our life harder else.
|
||||||
local arraypat = sp0 * "[" * sp0 * tok.rvar * sp0 * "]"
|
local arraypat = sp0 * "[" * sp0 * tok.rvar * sp0 * "]"
|
||||||
|
|
||||||
-- Have to bite the bullet here and list actor/player members with second parameters,
|
-- Have to bite the bullet here and list actor/player members with second
|
||||||
-- even though it's ugly to make it part of the syntax. Also, stuff like
|
-- parameters, even though it's ugly to make it part of the syntax. Also,
|
||||||
|
-- stuff like
|
||||||
-- actor[xxx].loogiex parm2 x
|
-- actor[xxx].loogiex parm2 x
|
||||||
-- will be wrongly accepted at the parsing stage because we don't discriminate between
|
-- will be wrongly accepted at the parsing stage (loogiex is player's member)
|
||||||
-- actor and player (but it will be rejected later).
|
-- because we don't discriminate between actor and player here.
|
||||||
local parm2memberpat = (Pat("htg_t") + "loogiex" + "loogiey" + "ammo_amount" +
|
local parm2memberpat = lpeg.C(Pat("htg_t") + "loogiex" + "loogiey" + "ammo_amount" +
|
||||||
"weaprecs" + "gotweapon" + "pals" + "max_ammo_amount") * sp1 * tok.rvar
|
"weaprecs" + "gotweapon" + "pals" + "max_ammo_amount") * sp1 * tok.rvar
|
||||||
-- The member name must match keywords, too (_all), because e.g. cstat is a member
|
-- The member name must match keywords, too (_all), because e.g. cstat is a member
|
||||||
-- of sprite[].
|
-- of sprite[].
|
||||||
local memberpat = sp0 * "." * sp0 * (parm2memberpat + tok.identifier_all)
|
local bothmemberpat = sp0 * "." * sp0 * lpeg.Ct(parm2memberpat + tok.identifier_all)
|
||||||
|
local singlememberpat = sp0 * "." * sp0 * tok.identifier_all
|
||||||
|
|
||||||
local getstructcmd = -- get<structname>[<idx>].<member> (<parm2>)? <<var>>
|
local getstructcmd = -- get<structname>[<idx>].<member> (<parm2>)? <<var>>
|
||||||
-- existence of a second parameter is determined later
|
arraypat * bothmemberpat * sp1 * tok.wvar
|
||||||
-- This is wrong, (sp1 id)? will match (sp1 wvar) if there's no 2nd param:
|
|
||||||
-- arraypat * memberpat * (sp1 * tok.identifier)^-1 * sp1 * tok.wvar
|
|
||||||
arraypat * memberpat * sp1 * (tok.rvar * sp1 * tok.wvar + tok.wvar)
|
|
||||||
|
|
||||||
local setstructcmd = -- set<structname>[<idx>].<member> (<parm2>)? <var>
|
local setstructcmd = -- set<structname>[<idx>].<<member>> (<parm2>)? <var>
|
||||||
-- existence of a second parameter is determined later
|
arraypat * bothmemberpat * sp1 * tok.rvar
|
||||||
arraypat * memberpat * sp1 * (tok.rvar * sp1 * tok.rvar + tok.rvar)
|
|
||||||
|
|
||||||
local getperxvarcmd = -- get<actor/player>var[<idx>].<member> <<var>>
|
local getperxvarcmd = -- get<actor/player>var[<idx>].<member> <<var>>
|
||||||
arraypat * memberpat * sp1 * tok.wvar
|
arraypat * singlememberpat * sp1 * tok.wvar
|
||||||
|
|
||||||
local setperxvarcmd = -- set<actor/player>var[<idx>].<member> <var>
|
local setperxvarcmd = -- set<actor/player>var[<idx>].<<member>> <var>
|
||||||
arraypat * memberpat * sp1 * tok.rvar
|
arraypat * singlememberpat * sp1 * tok.rvar
|
||||||
|
|
||||||
|
local Access =
|
||||||
|
{
|
||||||
|
-- <writtenp>: whether the actor is written to.
|
||||||
|
actor = function(writtenp, index, membertab)
|
||||||
|
assert(type(membertab)=="table")
|
||||||
|
local member, parm2 = membertab[1], membertab[2]
|
||||||
|
assert(member ~= nil)
|
||||||
|
|
||||||
|
-- Look up array+member name first, e.g. "spriteext[%s].angoff".
|
||||||
|
local armembcode = conl.ActorLabels[member]
|
||||||
|
if (armembcode == nil) then
|
||||||
|
errprintf("invalid CON actor member `%s'", member)
|
||||||
|
return "_MEMBINVALID"
|
||||||
|
end
|
||||||
|
|
||||||
|
if (type(armembcode)=="table") then
|
||||||
|
-- Read and write accesses differ.
|
||||||
|
armembcode = armembcode[writtenp and 2 or 1]
|
||||||
|
if (armembcode==nil) then
|
||||||
|
assert(writtenp)
|
||||||
|
errprintf("write access to CON actor[].%s is not available", member)
|
||||||
|
return "_MEMBRO"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local _, numparms = armembcode:gsub("%%s", "%%s", 2)
|
||||||
|
if (#membertab ~= numparms) then
|
||||||
|
local one = numparms==1
|
||||||
|
errprintf("CON actor[].%s has %s parameter%s, but %d given", member,
|
||||||
|
one and "one" or "two", one and "" or "s", #membertab)
|
||||||
|
return "_MEMBINVPARM"
|
||||||
|
end
|
||||||
|
|
||||||
|
return format(armembcode, index, parm2)
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
||||||
|
local function GetStructCmd(accessfunc)
|
||||||
|
local pattern = getstructcmd / function(idx, memb, var)
|
||||||
|
return format("%s=%s", var, accessfunc(false, idx, memb))
|
||||||
|
end
|
||||||
|
return pattern
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
-- Various inner command handling functions / string capture strings.
|
-- Various inner command handling functions / string capture strings.
|
||||||
|
@ -1166,7 +1206,7 @@ local Cinner = {
|
||||||
/ handle.state,
|
/ handle.state,
|
||||||
|
|
||||||
--- 1. get*, set*
|
--- 1. get*, set*
|
||||||
getactor = getstructcmd,
|
getactor = GetStructCmd(Access.actor),
|
||||||
getinput = getstructcmd,
|
getinput = getstructcmd,
|
||||||
getplayer = getstructcmd,
|
getplayer = getstructcmd,
|
||||||
getprojectile = getstructcmd,
|
getprojectile = getstructcmd,
|
||||||
|
@ -1175,9 +1215,13 @@ local Cinner = {
|
||||||
gettspr = getstructcmd,
|
gettspr = getstructcmd,
|
||||||
-- NOTE: {get,set}userdef is the only struct that can be accessed without
|
-- NOTE: {get,set}userdef is the only struct that can be accessed without
|
||||||
-- an "array part", e.g. H266MOD has "setuserdef .weaponswitch 0" (space
|
-- an "array part", e.g. H266MOD has "setuserdef .weaponswitch 0" (space
|
||||||
-- between keyword and "." is mandatory)
|
-- between keyword and "." is mandatory).
|
||||||
getuserdef = (arraypat + sp1) * memberpat * sp1 * (tok.rvar * sp1 * tok.wvar + tok.wvar),
|
-- NOTE2: userdef has at least three members with a second parameter:
|
||||||
-- getuserdef = getstructcmd,
|
-- user_name, ridecule, savegame. Then there's wchoice. Given that they're
|
||||||
|
-- arrays, I highly doubt that they worked (much less were safe) in CON.
|
||||||
|
-- We disallow them unless CONs in the wild crop up that actually used
|
||||||
|
-- these.
|
||||||
|
getuserdef = (arraypat + sp1)/{} * singlememberpat * sp1 * tok.wvar,
|
||||||
getwall = getstructcmd,
|
getwall = getstructcmd,
|
||||||
|
|
||||||
getactorvar = getperxvarcmd,
|
getactorvar = getperxvarcmd,
|
||||||
|
@ -1190,8 +1234,7 @@ local Cinner = {
|
||||||
setsector = setstructcmd,
|
setsector = setstructcmd,
|
||||||
setthisprojectile = setstructcmd,
|
setthisprojectile = setstructcmd,
|
||||||
settspr = setstructcmd,
|
settspr = setstructcmd,
|
||||||
setuserdef = (arraypat + sp1) * memberpat * sp1 * (tok.rvar * sp1 * tok.wvar + tok.rvar),
|
setuserdef = (arraypat + sp1)/{} * singlememberpat * sp1 * tok.rvar,
|
||||||
-- setuserdef = setstructcmd,
|
|
||||||
setwall = setstructcmd,
|
setwall = setstructcmd,
|
||||||
|
|
||||||
setactorvar = setperxvarcmd,
|
setactorvar = setperxvarcmd,
|
||||||
|
@ -1983,7 +2026,7 @@ local Grammar = Pat{
|
||||||
+ Range("09")^1)
|
+ Range("09")^1)
|
||||||
) / parse_number,
|
) / parse_number,
|
||||||
|
|
||||||
t_identifier_all = t_broken_identifier + t_good_identifier,
|
t_identifier_all = lpeg.C(t_broken_identifier + t_good_identifier),
|
||||||
-- NOTE: -conl.keyword alone would be wrong, e.g. "state breakobject":
|
-- NOTE: -conl.keyword alone would be wrong, e.g. "state breakobject":
|
||||||
-- NOTE 2: The + "[" is so that stuff like
|
-- NOTE 2: The + "[" is so that stuff like
|
||||||
-- getactor[THISACTOR].x x
|
-- getactor[THISACTOR].x x
|
||||||
|
@ -1992,7 +2035,7 @@ local Grammar = Pat{
|
||||||
-- getactor[THISACTOR].x x
|
-- getactor[THISACTOR].x x
|
||||||
-- getactor [THISACTOR].y y
|
-- getactor [THISACTOR].y y
|
||||||
-- This is in need of cleanup!
|
-- This is in need of cleanup!
|
||||||
t_identifier = -NotKeyw(conl.keyword * (sp1 + "[")) * lpeg.C(tok.identifier_all),
|
t_identifier = -NotKeyw(conl.keyword * (sp1 + "[")) * tok.identifier_all,
|
||||||
-- TODO?: SST TC has e.g. "1267AT", relying on it to be parsed as a number "1267".
|
-- TODO?: SST TC has e.g. "1267AT", relying on it to be parsed as a number "1267".
|
||||||
-- However, this conflicts with bad-identifiers, so it should be checked last.
|
-- However, this conflicts with bad-identifiers, so it should be checked last.
|
||||||
-- This would also handle LNGA2's "00000000h", though would give problems with
|
-- This would also handle LNGA2's "00000000h", though would give problems with
|
||||||
|
@ -2001,9 +2044,12 @@ local Grammar = Pat{
|
||||||
|
|
||||||
-- Defines and constants can take the place of vars that are only read.
|
-- Defines and constants can take the place of vars that are only read.
|
||||||
-- XXX: now, when tok.rvar fails, the tok.define failure message is printed.
|
-- XXX: now, when tok.rvar fails, the tok.define failure message is printed.
|
||||||
t_rvar = tok.arrayexp + lpeg.Cmt(tok.identifier, maybe_gamevar_Cmt) + tok.define,
|
t_rvar = Var("t_botharrayexp") / function() --[[warnprintf("t_rvar: array exprs NYI")--]] return "_NYIVAR" end
|
||||||
-- not so with written-to vars:
|
+ lpeg.Cmt(tok.identifier, maybe_gamevar_Cmt) + tok.define,
|
||||||
t_wvar = tok.arrayexp + (tok.identifier / function(id) return lookup_gamevar(id, true) end),
|
-- For written-to vars, only (non-parm2) array exprs and writable gamevars
|
||||||
|
-- are permitted. NOTE: C-CON doesn't support inline array exprs here.
|
||||||
|
t_wvar = Var("t_singlearrayexp") / function() errprintf("t_wvar: array exprs NYI") return "_NYIVAR" end
|
||||||
|
+ (tok.identifier / function(id) return lookup_gamevar(id, true) end),
|
||||||
|
|
||||||
t_move =
|
t_move =
|
||||||
POS()*tok.identifier / function(...) return lookup_composite(LABEL.MOVE, ...) end +
|
POS()*tok.identifier / function(...) return lookup_composite(LABEL.MOVE, ...) end +
|
||||||
|
@ -2017,7 +2063,9 @@ local Grammar = Pat{
|
||||||
POS()*tok.identifier / function(...) return lookup_composite(LABEL.ACTION, ...) end +
|
POS()*tok.identifier / function(...) return lookup_composite(LABEL.ACTION, ...) end +
|
||||||
POS()*tok.number / function(...) return check_composite_literal(LABEL.ACTION, ...) end,
|
POS()*tok.number / function(...) return check_composite_literal(LABEL.ACTION, ...) end,
|
||||||
|
|
||||||
t_arrayexp = tok.identifier * arraypat * memberpat^-1,
|
-- New-style inline arrays and structures.
|
||||||
|
t_botharrayexp = tok.identifier * arraypat * bothmemberpat^-1,
|
||||||
|
t_singlearrayexp = tok.identifier * arraypat * singlememberpat^-1,
|
||||||
|
|
||||||
-- SWITCH
|
-- SWITCH
|
||||||
switch_stmt = Keyw("switch") * sp1 * tok.rvar *
|
switch_stmt = Keyw("switch") * sp1 * tok.rvar *
|
||||||
|
|
Loading…
Reference in a new issue