mirror of
https://github.com/ZDoom/raze-gles.git
synced 2025-01-11 18:50:46 +00:00
Lunatic: prototype of The Translator.
Currently syntax only. Parses the original scandcode 0x1d files, which is harder than you'd imagine given the relatively simple structure. Chokes on new-gen custom stuff. git-svn-id: https://svn.eduke32.com/eduke32@2594 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
parent
dbd8745620
commit
a18a89b513
2 changed files with 1147 additions and 0 deletions
370
polymer/eduke32/source/lunatic/con_lang.lua
Normal file
370
polymer/eduke32/source/lunatic/con_lang.lua
Normal file
|
@ -0,0 +1,370 @@
|
||||||
|
-- Use this file like
|
||||||
|
-- require("lpeg")
|
||||||
|
-- con_keyword = dofile("con_lang.lua")
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
lpeg.P(false) +
|
||||||
|
"{" +
|
||||||
|
"}" +
|
||||||
|
"action" +
|
||||||
|
"activatebysector" +
|
||||||
|
"activatecheat" +
|
||||||
|
"actor" +
|
||||||
|
"addammo" +
|
||||||
|
"addinventory" +
|
||||||
|
"addkills" +
|
||||||
|
"addlog" +
|
||||||
|
"addlogvar" +
|
||||||
|
"addphealth" +
|
||||||
|
"addstrength" +
|
||||||
|
"addvar" +
|
||||||
|
"addvarvar" +
|
||||||
|
"addweapon" +
|
||||||
|
"addweaponvar" +
|
||||||
|
"ai" +
|
||||||
|
"andvar" +
|
||||||
|
"andvarvar" +
|
||||||
|
"angoff" +
|
||||||
|
"angoffvar" +
|
||||||
|
"betaname" +
|
||||||
|
"break" +
|
||||||
|
"cactor" +
|
||||||
|
"calchypotenuse" +
|
||||||
|
"cansee" +
|
||||||
|
"canseespr" +
|
||||||
|
"case" +
|
||||||
|
"changespritesect" +
|
||||||
|
"changespritestat" +
|
||||||
|
"cheatkeys" +
|
||||||
|
"checkactivatormotion" +
|
||||||
|
"checkavailinven" +
|
||||||
|
"checkavailweapon" +
|
||||||
|
"clearmapstate" +
|
||||||
|
"clipdist" +
|
||||||
|
"clipmove" +
|
||||||
|
"clipmovenoslide" +
|
||||||
|
"cmenu" +
|
||||||
|
"copy" +
|
||||||
|
"cos" +
|
||||||
|
"count" +
|
||||||
|
"cstat" +
|
||||||
|
"cstator" +
|
||||||
|
"debris" +
|
||||||
|
"debug" +
|
||||||
|
"default" +
|
||||||
|
"define" +
|
||||||
|
"definecheat" +
|
||||||
|
"definegamefuncname" +
|
||||||
|
"definegametype" +
|
||||||
|
"definelevelname" +
|
||||||
|
"defineprojectile" +
|
||||||
|
"definequote" +
|
||||||
|
"defineskillname" +
|
||||||
|
"definesound" +
|
||||||
|
"definevolumename" +
|
||||||
|
"digitalnumber" +
|
||||||
|
"digitalnumberz" +
|
||||||
|
"displayrand" +
|
||||||
|
"displayrandvar" +
|
||||||
|
"displayrandvarvar" +
|
||||||
|
"dist" +
|
||||||
|
"divvar" +
|
||||||
|
"divvarvar" +
|
||||||
|
"dragpoint" +
|
||||||
|
"dynamicremap" +
|
||||||
|
"echo" +
|
||||||
|
"else" +
|
||||||
|
"enda" +
|
||||||
|
"endevent" +
|
||||||
|
"endofgame" +
|
||||||
|
"ends" +
|
||||||
|
"endswitch" +
|
||||||
|
"enhanced" +
|
||||||
|
"eqspawn" +
|
||||||
|
"eqspawnvar" +
|
||||||
|
"eshoot" +
|
||||||
|
"eshootvar" +
|
||||||
|
"espawn" +
|
||||||
|
"espawnvar" +
|
||||||
|
"eventloadactor" +
|
||||||
|
"ezshoot" +
|
||||||
|
"ezshootvar" +
|
||||||
|
"fall" +
|
||||||
|
"findnearactor" +
|
||||||
|
"findnearactor3d" +
|
||||||
|
"findnearactor3dvar" +
|
||||||
|
"findnearactorvar" +
|
||||||
|
"findnearactorz" +
|
||||||
|
"findnearactorzvar" +
|
||||||
|
"findnearsprite" +
|
||||||
|
"findnearsprite3d" +
|
||||||
|
"findnearsprite3dvar" +
|
||||||
|
"findnearspritevar" +
|
||||||
|
"findnearspritez" +
|
||||||
|
"findnearspritezvar" +
|
||||||
|
"findotherplayer" +
|
||||||
|
"findplayer" +
|
||||||
|
"flash" +
|
||||||
|
"gamearray" +
|
||||||
|
"gamestartup" +
|
||||||
|
"gametext" +
|
||||||
|
"gametextz" +
|
||||||
|
"gamevar" +
|
||||||
|
"getactor" +
|
||||||
|
"getactorangle" +
|
||||||
|
"getactorvar" +
|
||||||
|
"getangle" +
|
||||||
|
"getangletotarget" +
|
||||||
|
"getarraysize" +
|
||||||
|
"getceilzofslope" +
|
||||||
|
"getcurraddress" +
|
||||||
|
"getflorzofslope" +
|
||||||
|
"getincangle" +
|
||||||
|
"getinput" +
|
||||||
|
"getkeyname" +
|
||||||
|
"getlastpal" +
|
||||||
|
"getplayer" +
|
||||||
|
"getplayerangle" +
|
||||||
|
"getplayervar" +
|
||||||
|
"getpname" +
|
||||||
|
"getprojectile" +
|
||||||
|
"getsector" +
|
||||||
|
"gettextureceiling" +
|
||||||
|
"gettexturefloor" +
|
||||||
|
"getthisprojectile" +
|
||||||
|
"getticks" +
|
||||||
|
"gettimedate" +
|
||||||
|
"gettspr" +
|
||||||
|
"getuserdef" +
|
||||||
|
"getwall" +
|
||||||
|
"getzrange" +
|
||||||
|
"globalsound" +
|
||||||
|
"globalsoundvar" +
|
||||||
|
"gmaxammo" +
|
||||||
|
"guniqhudid" +
|
||||||
|
"guts" +
|
||||||
|
"headspritesect" +
|
||||||
|
"headspritestat" +
|
||||||
|
"hitradius" +
|
||||||
|
"hitradiusvar" +
|
||||||
|
"hitscan" +
|
||||||
|
"ifaction" +
|
||||||
|
"ifactioncount" +
|
||||||
|
"ifactor" +
|
||||||
|
"ifactornotstayput" +
|
||||||
|
"ifactorsound" +
|
||||||
|
"ifai" +
|
||||||
|
"ifangdiffl" +
|
||||||
|
"ifawayfromwall" +
|
||||||
|
"ifbulletnear" +
|
||||||
|
"ifcansee" +
|
||||||
|
"ifcanseetarget" +
|
||||||
|
"ifcanshoottarget" +
|
||||||
|
"ifceilingdistl" +
|
||||||
|
"ifclient" +
|
||||||
|
"ifcount" +
|
||||||
|
"ifdead" +
|
||||||
|
"iffloordistl" +
|
||||||
|
"ifgapzl" +
|
||||||
|
"ifgotweaponce" +
|
||||||
|
"ifhitspace" +
|
||||||
|
"ifhitweapon" +
|
||||||
|
"ifinouterspace" +
|
||||||
|
"ifinspace" +
|
||||||
|
"ifinwater" +
|
||||||
|
"ifmove" +
|
||||||
|
"ifmultiplayer" +
|
||||||
|
"ifnosounds" +
|
||||||
|
"ifnotmoving" +
|
||||||
|
"ifonwater" +
|
||||||
|
"ifoutside" +
|
||||||
|
"ifp" +
|
||||||
|
"ifpdistg" +
|
||||||
|
"ifpdistl" +
|
||||||
|
"ifphealthl" +
|
||||||
|
"ifpinventory" +
|
||||||
|
"ifrespawn" +
|
||||||
|
"ifrnd" +
|
||||||
|
"ifserver" +
|
||||||
|
"ifsound" +
|
||||||
|
"ifspawnedby" +
|
||||||
|
"ifspritepal" +
|
||||||
|
"ifsquished" +
|
||||||
|
"ifstrength" +
|
||||||
|
"ifvarand" +
|
||||||
|
"ifvare" +
|
||||||
|
"ifvareither" +
|
||||||
|
"ifvarg" +
|
||||||
|
"ifvarl" +
|
||||||
|
"ifvarn" +
|
||||||
|
"ifvaror" +
|
||||||
|
"ifvarvarand" +
|
||||||
|
"ifvarvare" +
|
||||||
|
"ifvarvareither" +
|
||||||
|
"ifvarvarg" +
|
||||||
|
"ifvarvarl" +
|
||||||
|
"ifvarvarn" +
|
||||||
|
"ifvarvaror" +
|
||||||
|
"ifvarvarxor" +
|
||||||
|
"ifvarxor" +
|
||||||
|
"ifwasweapon" +
|
||||||
|
"include" +
|
||||||
|
"includedefault" +
|
||||||
|
"inittimer" +
|
||||||
|
"insertspriteq" +
|
||||||
|
"jump" +
|
||||||
|
"killit" +
|
||||||
|
"ldist" +
|
||||||
|
"lineintersect" +
|
||||||
|
"loadmapstate" +
|
||||||
|
"lockplayer" +
|
||||||
|
"lotsofglass" +
|
||||||
|
"mail" +
|
||||||
|
"mikesnd" +
|
||||||
|
"minitext" +
|
||||||
|
"modvar" +
|
||||||
|
"modvarvar" +
|
||||||
|
"money" +
|
||||||
|
"move" +
|
||||||
|
"movesprite" +
|
||||||
|
"mulscale" +
|
||||||
|
"mulvar" +
|
||||||
|
"mulvarvar" +
|
||||||
|
"music" +
|
||||||
|
"myos" +
|
||||||
|
"myospal" +
|
||||||
|
"myospalx" +
|
||||||
|
"myosx" +
|
||||||
|
"neartag" +
|
||||||
|
"nextspritesect" +
|
||||||
|
"nextspritestat" +
|
||||||
|
"nullop" +
|
||||||
|
"onevent" +
|
||||||
|
"operate" +
|
||||||
|
"operateactivators" +
|
||||||
|
"operatemasterswitches" +
|
||||||
|
"operaterespawns" +
|
||||||
|
"operatesectors" +
|
||||||
|
"orvar" +
|
||||||
|
"orvarvar" +
|
||||||
|
"palfrom" +
|
||||||
|
"paper" +
|
||||||
|
"pkick" +
|
||||||
|
"precache" +
|
||||||
|
"prevspritesect" +
|
||||||
|
"prevspritestat" +
|
||||||
|
"pstomp" +
|
||||||
|
"qgetsysstr" +
|
||||||
|
"qspawn" +
|
||||||
|
"qspawnvar" +
|
||||||
|
"qsprintf" +
|
||||||
|
"qstrcat" +
|
||||||
|
"qstrcpy" +
|
||||||
|
"qstrlen" +
|
||||||
|
"qstrncat" +
|
||||||
|
"qsubstr" +
|
||||||
|
"quake" +
|
||||||
|
"quote" +
|
||||||
|
"randvar" +
|
||||||
|
"randvarvar" +
|
||||||
|
"rayintersect" +
|
||||||
|
"readarrayfromfile" +
|
||||||
|
"readgamevar" +
|
||||||
|
"redefinequote" +
|
||||||
|
"resetactioncount" +
|
||||||
|
"resetcount" +
|
||||||
|
"resetplayer" +
|
||||||
|
"resizearray" +
|
||||||
|
"respawnhitag" +
|
||||||
|
"return" +
|
||||||
|
"rotatepoint" +
|
||||||
|
"rotatesprite" +
|
||||||
|
"rotatesprite16" +
|
||||||
|
"save" +
|
||||||
|
"savegamevar" +
|
||||||
|
"savemapstate" +
|
||||||
|
"savenn" +
|
||||||
|
"scriptsize" +
|
||||||
|
"sectclearinterpolation" +
|
||||||
|
"sectgethitag" +
|
||||||
|
"sectgetlotag" +
|
||||||
|
"sectorofwall" +
|
||||||
|
"sectsetinterpolation" +
|
||||||
|
"setactor" +
|
||||||
|
"setactorangle" +
|
||||||
|
"setactorsoundpitch" +
|
||||||
|
"setactorvar" +
|
||||||
|
"setarray" +
|
||||||
|
"setaspect" +
|
||||||
|
"setcfgname" +
|
||||||
|
"setdefname" +
|
||||||
|
"setgamename" +
|
||||||
|
"setgamepalette" +
|
||||||
|
"setinput" +
|
||||||
|
"setplayer" +
|
||||||
|
"setplayerangle" +
|
||||||
|
"setplayervar" +
|
||||||
|
"setprojectile" +
|
||||||
|
"setsector" +
|
||||||
|
"setsprite" +
|
||||||
|
"setthisprojectile" +
|
||||||
|
"settspr" +
|
||||||
|
"setuserdef" +
|
||||||
|
"setvar" +
|
||||||
|
"setvarvar" +
|
||||||
|
"setwall" +
|
||||||
|
"shiftvarl" +
|
||||||
|
"shiftvarr" +
|
||||||
|
"shoot" +
|
||||||
|
"shootvar" +
|
||||||
|
"showview" +
|
||||||
|
"showviewunbiased" +
|
||||||
|
"sin" +
|
||||||
|
"sizeat" +
|
||||||
|
"sizeto" +
|
||||||
|
"sleeptime" +
|
||||||
|
"smaxammo" +
|
||||||
|
"sound" +
|
||||||
|
"soundonce" +
|
||||||
|
"soundoncevar" +
|
||||||
|
"soundvar" +
|
||||||
|
"spawn" +
|
||||||
|
"spgethitag" +
|
||||||
|
"spgetlotag" +
|
||||||
|
"spriteflags" +
|
||||||
|
"spritenopal" +
|
||||||
|
"spritenoshade" +
|
||||||
|
"spritenvg" +
|
||||||
|
"spritepal" +
|
||||||
|
"spriteshadow" +
|
||||||
|
"sqrt" +
|
||||||
|
"ssp" +
|
||||||
|
"startlevel" +
|
||||||
|
"starttrack" +
|
||||||
|
"starttrackvar" +
|
||||||
|
"state" +
|
||||||
|
"stopactorsound" +
|
||||||
|
"stopallsounds" +
|
||||||
|
"stopsound" +
|
||||||
|
"stopsoundvar" +
|
||||||
|
"strength" +
|
||||||
|
"subvar" +
|
||||||
|
"subvarvar" +
|
||||||
|
"switch" +
|
||||||
|
"time" +
|
||||||
|
"tip" +
|
||||||
|
"tossweapon" +
|
||||||
|
"updatesector" +
|
||||||
|
"updatesectorz" +
|
||||||
|
"useractor" +
|
||||||
|
"userquote" +
|
||||||
|
"wackplayer" +
|
||||||
|
"whilevarn" +
|
||||||
|
"whilevarvarn" +
|
||||||
|
"writearraytofile" +
|
||||||
|
"xorvar" +
|
||||||
|
"xorvarvar" +
|
||||||
|
"zshoot" +
|
||||||
|
"zshootvar" +
|
||||||
|
lpeg.P(false)
|
777
polymer/eduke32/source/lunatic/lunacon.lua
Normal file
777
polymer/eduke32/source/lunatic/lunacon.lua
Normal file
|
@ -0,0 +1,777 @@
|
||||||
|
-- LunaCON CON to Lunatic translator
|
||||||
|
-- requires LPeg, http://www.inf.puc-rio.br/~roberto/lpeg/lpeg.html
|
||||||
|
|
||||||
|
local lpeg = require("lpeg")
|
||||||
|
|
||||||
|
local Pat, Set, Range, Var = lpeg.P, lpeg.S, lpeg.R, lpeg.V
|
||||||
|
|
||||||
|
|
||||||
|
---- All keywords pattern -- needed for CON syntax
|
||||||
|
local con_keyword = dofile("con_lang.lua")
|
||||||
|
|
||||||
|
|
||||||
|
local function match_until(matchsp, untilsp) -- (!untilsp matchsp)* in PEG
|
||||||
|
-- sp: string or pattern
|
||||||
|
return (matchsp - Pat(untilsp))^0
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
----==== patterns ====----
|
||||||
|
|
||||||
|
---- basic ones
|
||||||
|
local newline = Pat("\n") -- need to do stuff on newline later...
|
||||||
|
local anychar = Pat(1)
|
||||||
|
-- comments
|
||||||
|
local comment = "/*" * match_until(anychar, "*/") * "*/"
|
||||||
|
local linecomment = "//" * match_until(anychar, newline)
|
||||||
|
local whitespace = Var("whitespace")
|
||||||
|
local sp0 = whitespace^0
|
||||||
|
local sp1 = whitespace^1 -- + (-1) -- matches EOF, too
|
||||||
|
local alpha = Range("AZ", "az") -- locale?
|
||||||
|
local alphanum = alpha + Range("09")
|
||||||
|
local alnumtok = alphanum + Set("{}/\\*-_.") -- see isaltok() in gamedef.c
|
||||||
|
|
||||||
|
--- basic lexical elements ("tokens")
|
||||||
|
local t_number = Range("09")^1 + (Pat("0x") + "0X")*Range("09", "af")^1
|
||||||
|
-- Valid identifier names are disjunct from keywords!
|
||||||
|
-- XXX: CON is more permissive with identifier name characters:
|
||||||
|
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_filename = (anychar-Set(" \t\r\n"))^1 --alnumtok^1 -- XXX
|
||||||
|
local t_newline_term_str = match_until(anychar, newline)
|
||||||
|
|
||||||
|
-- new-style inline arrays and structures:
|
||||||
|
local t_arrayexp = Var("t_arrayexp")
|
||||||
|
|
||||||
|
-- defines and constants can take the place of vars that are only read:
|
||||||
|
local t_rvar = t_arrayexp + t_define
|
||||||
|
-- not so with written-to vars:
|
||||||
|
local t_wvar = t_arrayexp + t_identifier
|
||||||
|
|
||||||
|
|
||||||
|
---- helper patterns / pattern constructing functions
|
||||||
|
local maybe_quoted_filename = ('"' * t_filename * '"' + t_filename)
|
||||||
|
local newline_term_string = (whitespace-newline)^1 * t_newline_term_str -- XXX: empty string?
|
||||||
|
|
||||||
|
|
||||||
|
-- (sp1 * t_define) repeated exactly n times
|
||||||
|
local function n_defines(n) -- works well only for small n
|
||||||
|
local pat = Pat(true)
|
||||||
|
for i=1,n do
|
||||||
|
pat = sp1 * t_define * pat
|
||||||
|
end
|
||||||
|
return pat
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local D, R, W, I = -1, -2, -3, -4;
|
||||||
|
|
||||||
|
-- Generic command pattern, types given by varargs.
|
||||||
|
-- The command name to be matched is attached later.
|
||||||
|
-- Example:
|
||||||
|
-- "command" writtenvar readvar def def: gencmd(W,R,D,D)
|
||||||
|
-- --> sp1 * t_wvar * sp1 * t_rvar * sp1 * t_define * sp1 * t_define
|
||||||
|
-- "command_with_no_args": gencmd()
|
||||||
|
-- --> Pat(true)
|
||||||
|
local function cmd(...)
|
||||||
|
local pat = Pat(true)
|
||||||
|
local vartypes = {...}
|
||||||
|
|
||||||
|
local spat = ""
|
||||||
|
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
|
||||||
|
end
|
||||||
|
|
||||||
|
return pat
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- The command names will be attached to the front of the patterns later!
|
||||||
|
|
||||||
|
--== Top level CON commands ==--
|
||||||
|
local Co = {
|
||||||
|
--- 1. Preprocessor
|
||||||
|
include = sp1 * maybe_quoted_filename,
|
||||||
|
includedefault = cmd(),
|
||||||
|
define = cmd(I,D),
|
||||||
|
--define = sp1 * t_identifier * sp1 * t_define,
|
||||||
|
|
||||||
|
--- 2. Defines and Meta-Settings
|
||||||
|
dynamicremap = cmd(),
|
||||||
|
setcfgname = sp1 * t_filename,
|
||||||
|
setdefname = sp1 * t_filename,
|
||||||
|
setgamename = newline_term_string,
|
||||||
|
|
||||||
|
precache = cmd(D,D,D),
|
||||||
|
scriptsize = cmd(D), -- unused
|
||||||
|
cheatkeys = cmd(D,D),
|
||||||
|
|
||||||
|
definecheat = newline_term_string, -- XXX: actually tricker syntax (TS)
|
||||||
|
definegamefuncname = newline_term_string, -- XXX: TS?
|
||||||
|
definegametype = n_defines(2) * newline_term_string,
|
||||||
|
definelevelname = n_defines(2) * newline_term_string, -- XXX: TS
|
||||||
|
defineskillname = sp1 * t_define * newline_term_string,
|
||||||
|
definevolumename = sp1 * t_define * newline_term_string,
|
||||||
|
|
||||||
|
definequote = sp1 * t_define * newline_term_string,
|
||||||
|
defineprojectile = cmd(D,D,D),
|
||||||
|
definesound = sp1 * t_define * sp1 * maybe_quoted_filename * n_defines(5), -- XXX: TS
|
||||||
|
|
||||||
|
-- XXX: need to see how that behaves with e.g. stuff like gamevar.ogg:
|
||||||
|
music = match_until(sp1 * t_filename, con_keyword),
|
||||||
|
|
||||||
|
--- 3. Game Settings
|
||||||
|
-- gamestartup has 25/29 fixed defines, depending on 1.3D/1.5 version:
|
||||||
|
gamestartup = (sp1 * t_define)^25 * (sp1 * t_define)^-4,
|
||||||
|
spritenopal = cmd(D),
|
||||||
|
spritenoshade = cmd(D),
|
||||||
|
spritenvg = cmd(D),
|
||||||
|
spriteshadow = cmd(D),
|
||||||
|
|
||||||
|
spriteflags = cmd(D,D), -- also see inner
|
||||||
|
|
||||||
|
--- 4. Game Variables / Arrays
|
||||||
|
gamevar = cmd(I,D,D),
|
||||||
|
gamearray = cmd(I,D),
|
||||||
|
|
||||||
|
--- 5. Top level commands that are also run-time commands
|
||||||
|
action = sp1 * t_identifier * (sp1 * t_define)^-5,
|
||||||
|
ai = sp1 * t_identifier * (sp1 * t_define)^0,
|
||||||
|
move = sp1 * t_identifier * (sp1 * t_define)^-2,
|
||||||
|
|
||||||
|
--- 6. Deprecated TLCs
|
||||||
|
betaname = newline_term_string,
|
||||||
|
enhanced = cmd(D),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
--== Run time CON commands ==--
|
||||||
|
--- 1. Gamevar Operators
|
||||||
|
|
||||||
|
local varop = cmd(W,D)
|
||||||
|
local varvarop = cmd(W,R)
|
||||||
|
|
||||||
|
-- t_define is t_rvar without t_arrayexp, actually, so that no nesting is allowed:
|
||||||
|
local arraypat = sp0 * "[" * sp0 * t_define * sp0 * "]"
|
||||||
|
-- The member name must match keywords, too (_all), because e.g. cstat is a member
|
||||||
|
-- of sprite[]
|
||||||
|
local memberpat = sp0 * "." * sp0 * t_identifier_all
|
||||||
|
|
||||||
|
local getstructcmd = -- get<structname>[<idx>].<member> (<parm2>)? <<var>>
|
||||||
|
-- existence of a second parameter is determined later
|
||||||
|
-- This is wrong, (sp1 id)? will match (sp1 wvar) if there's no 2nd param:
|
||||||
|
-- arraypat * memberpat * (sp1 * t_identifier)^-1 * sp1 * t_wvar
|
||||||
|
-- XXX: This is still wrong.
|
||||||
|
arraypat * memberpat * sp1 * (t_identifier * sp1 * t_wvar + t_wvar)
|
||||||
|
|
||||||
|
local setstructcmd = -- set<structname>[<idx>].<member> (<parm2>)? <var>
|
||||||
|
-- existence of a second parameter is determined later
|
||||||
|
arraypat * memberpat * sp1 * (t_identifier * sp1 * t_rvar + t_rvar)
|
||||||
|
|
||||||
|
local getperxvarcmd = -- get<actor/player>var[<idx>].<member> <<var>>
|
||||||
|
arraypat * memberpat * sp1 * t_wvar
|
||||||
|
|
||||||
|
local setperxvarcmd = -- set<actor/player>var[<idx>].<member> <var>
|
||||||
|
arraypat * memberpat * sp1 * t_rvar
|
||||||
|
|
||||||
|
|
||||||
|
local Ci = {
|
||||||
|
-- these can appear anywhere in the script
|
||||||
|
["break"] = cmd(),
|
||||||
|
["return"] = cmd(),
|
||||||
|
|
||||||
|
state = cmd(I),
|
||||||
|
|
||||||
|
--- 1. get*, set*
|
||||||
|
getactor = getstructcmd,
|
||||||
|
getinput = getstructcmd,
|
||||||
|
getplayer = getstructcmd,
|
||||||
|
getprojectile = getstructcmd,
|
||||||
|
getsector = getstructcmd,
|
||||||
|
getsprite = getstructcmd,
|
||||||
|
getthisprojectile = getstructcmd,
|
||||||
|
gettspr = getstructcmd,
|
||||||
|
getuserdef = getstructcmd,
|
||||||
|
getwall = getstructcmd,
|
||||||
|
|
||||||
|
getactorvar = getperxvarcmd,
|
||||||
|
getplayervar = getperxvarcmd,
|
||||||
|
|
||||||
|
setactor = setstructcmd,
|
||||||
|
setinput = setstructcmd,
|
||||||
|
setplayer = setstructcmd,
|
||||||
|
setprojectile = setstructcmd,
|
||||||
|
setsector = setstructcmd,
|
||||||
|
setsprite = setstructcmd,
|
||||||
|
setthisprojectile = setstructcmd,
|
||||||
|
settspr = setstructcmd,
|
||||||
|
setuserdef = setstructcmd,
|
||||||
|
setwall = setstructcmd,
|
||||||
|
|
||||||
|
setactorvar = setperxvarcmd,
|
||||||
|
setplayervar = setperxvarcmd,
|
||||||
|
|
||||||
|
setvarvar = varvarop,
|
||||||
|
addvarvar = varvarop,
|
||||||
|
subvarvar = varvarop,
|
||||||
|
mulvarvar = varvarop,
|
||||||
|
divvarvar = varvarop,
|
||||||
|
modvarvar = varvarop,
|
||||||
|
andvarvar = varvarop,
|
||||||
|
orvarvar = varvarop,
|
||||||
|
xorvarvar = varvarop,
|
||||||
|
randvarvar = varvarop,
|
||||||
|
|
||||||
|
setvar = varop,
|
||||||
|
addvar = varop,
|
||||||
|
subvar = varop,
|
||||||
|
mulvar = varop,
|
||||||
|
divvar = varop,
|
||||||
|
modvar = varop,
|
||||||
|
andvar = varop,
|
||||||
|
orvar = varop,
|
||||||
|
xorvar = varop,
|
||||||
|
randvar = varop,
|
||||||
|
shiftvarl = varop,
|
||||||
|
shiftvarr = varop,
|
||||||
|
|
||||||
|
--- 2. Math operations
|
||||||
|
sqrt = cmd(R,W),
|
||||||
|
calchypotenuse = cmd(W,R,R),
|
||||||
|
sin = cmd(W,R),
|
||||||
|
cos = cmd(W,R),
|
||||||
|
mulscale = cmd(W,R,R),
|
||||||
|
getangle = cmd(W,R,R),
|
||||||
|
getincangle = cmd(W,R,R),
|
||||||
|
|
||||||
|
--- 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,
|
||||||
|
|
||||||
|
cactor = cmd(D),
|
||||||
|
count = cmd(D),
|
||||||
|
cstator = cmd(D),
|
||||||
|
cstat = cmd(D),
|
||||||
|
clipdist = cmd(D),
|
||||||
|
sizeto = cmd(D,D),
|
||||||
|
sizeat = cmd(D,D),
|
||||||
|
strength = cmd(D),
|
||||||
|
addstrength = cmd(D),
|
||||||
|
spritepal = cmd(D),
|
||||||
|
|
||||||
|
hitradius = cmd(D,D,D,D,D),
|
||||||
|
hitradiusvar = cmd(R,R,R,R,R),
|
||||||
|
|
||||||
|
-- some commands taking read vars
|
||||||
|
eshootvar = cmd(R),
|
||||||
|
espawnvar = cmd(R),
|
||||||
|
qspawnvar = cmd(R),
|
||||||
|
eqspawnvar = cmd(R),
|
||||||
|
operaterespawns = cmd(R),
|
||||||
|
operatemasterswitches = cmd(R),
|
||||||
|
checkactivatormotion = cmd(R),
|
||||||
|
time = cmd(R), -- no-op
|
||||||
|
inittimer = cmd(R),
|
||||||
|
lockplayer = cmd(R),
|
||||||
|
shootvar = cmd(R),
|
||||||
|
quake = cmd(R),
|
||||||
|
jump = cmd(R),
|
||||||
|
cmenu = cmd(R),
|
||||||
|
soundvar = cmd(R),
|
||||||
|
globalsoundvar = cmd(R),
|
||||||
|
stopsoundvar = cmd(R),
|
||||||
|
soundoncevar = cmd(R),
|
||||||
|
angoffvar = cmd(R),
|
||||||
|
checkavailweapon = cmd(R),
|
||||||
|
checkavailinven = cmd(R),
|
||||||
|
guniqhudid = cmd(R),
|
||||||
|
savegamevar = cmd(R),
|
||||||
|
readgamevar = cmd(R),
|
||||||
|
userquote = cmd(R),
|
||||||
|
echo = cmd(R),
|
||||||
|
starttrackvar = cmd(R),
|
||||||
|
clearmapstate = cmd(R),
|
||||||
|
activatecheat = cmd(R),
|
||||||
|
setgamepalette = cmd(R),
|
||||||
|
|
||||||
|
-- some commands taking defines
|
||||||
|
addammo = cmd(D,D),
|
||||||
|
addweapon = cmd(D,D), -- exec SPECIAL HANDLING!
|
||||||
|
debris = cmd(D,D),
|
||||||
|
addinventory = cmd(D,D),
|
||||||
|
guts = cmd(D,D),
|
||||||
|
|
||||||
|
-- cont'd
|
||||||
|
addkills = cmd(D),
|
||||||
|
addphealth = cmd(D),
|
||||||
|
angoff = cmd(D),
|
||||||
|
debug = cmd(D),
|
||||||
|
endofgame = cmd(D),
|
||||||
|
eqspawn = cmd(D),
|
||||||
|
espawn = cmd(D),
|
||||||
|
globalsound = cmd(D),
|
||||||
|
lotsofglass = cmd(D),
|
||||||
|
mail = cmd(D),
|
||||||
|
money = cmd(D),
|
||||||
|
paper = cmd(D),
|
||||||
|
qspawn = cmd(D),
|
||||||
|
quote = cmd(D),
|
||||||
|
savenn = cmd(D),
|
||||||
|
save = cmd(D),
|
||||||
|
sleeptime = cmd(D),
|
||||||
|
soundonce = cmd(D),
|
||||||
|
sound = cmd(D),
|
||||||
|
spawn = cmd(D),
|
||||||
|
stopsound = cmd(D),
|
||||||
|
|
||||||
|
eshoot = cmd(D),
|
||||||
|
ezshoot = cmd(R,D),
|
||||||
|
ezshootvar = cmd(R,R),
|
||||||
|
shoot = cmd(D),
|
||||||
|
zshoot = cmd(R,D),
|
||||||
|
zshootvar = cmd(R,R),
|
||||||
|
|
||||||
|
fall = cmd(),
|
||||||
|
flash = cmd(),
|
||||||
|
getlastpal = cmd(),
|
||||||
|
insertspriteq = cmd(),
|
||||||
|
killit = cmd(),
|
||||||
|
mikesnd = cmd(),
|
||||||
|
nullop = cmd(),
|
||||||
|
operate = cmd(),
|
||||||
|
pkick = cmd(),
|
||||||
|
pstomp = cmd(),
|
||||||
|
resetactioncount = cmd(),
|
||||||
|
resetcount = cmd(),
|
||||||
|
resetplayer = cmd(),
|
||||||
|
respawnhitag = cmd(),
|
||||||
|
tip = cmd(),
|
||||||
|
tossweapon = cmd(),
|
||||||
|
wackplayer = cmd(),
|
||||||
|
|
||||||
|
-- sprite searching
|
||||||
|
findplayer = cmd(D,D),
|
||||||
|
findotherplayer = cmd(D,D),
|
||||||
|
findnearspritezvar = cmd(D,R,R,W),
|
||||||
|
findnearspritez = cmd(D,D,D,W),
|
||||||
|
findnearspritevar = cmd(D,R,W),
|
||||||
|
findnearsprite3dvar = cmd(D,R,W),
|
||||||
|
findnearsprite3d = cmd(D,D,W),
|
||||||
|
findnearsprite = cmd(D,D,W),
|
||||||
|
findnearactorzvar = cmd(D,R,R,W),
|
||||||
|
findnearactorz = cmd(D,D,D,W),
|
||||||
|
findnearactorvar = cmd(D,R,W),
|
||||||
|
findnearactor3dvar = cmd(D,R,W),
|
||||||
|
findnearactor3d = cmd(D,D,W),
|
||||||
|
findnearactor = cmd(D,D,W),
|
||||||
|
|
||||||
|
-- quotes
|
||||||
|
qsprintf = sp1 * t_rvar * sp1 * t_rvar * (sp1 * t_rvar)^-32,
|
||||||
|
qgetsysstr = cmd(R,R),
|
||||||
|
qstrcat = cmd(R,R),
|
||||||
|
qstrcpy = cmd(R,R),
|
||||||
|
qstrlen = cmd(R,R),
|
||||||
|
qstrncat = cmd(R,R),
|
||||||
|
qsubstr = cmd(R,R),
|
||||||
|
|
||||||
|
-- array stuff
|
||||||
|
copy = sp1 * t_identifier * arraypat * sp1 * t_identifier * arraypat,
|
||||||
|
setarray = sp1 * t_identifier * arraypat * sp1 * t_rvar,
|
||||||
|
|
||||||
|
activatebysector = cmd(R,R),
|
||||||
|
addlog = cmd(),
|
||||||
|
addlogvar = cmd(R),
|
||||||
|
addweaponvar = cmd(R,R), -- exec SPECIAL HANDLING!
|
||||||
|
cansee = cmd(R,R,R,R,R,R,R,R,W),
|
||||||
|
canseespr = cmd(R,R,W),
|
||||||
|
changespritesect = cmd(R,R),
|
||||||
|
changespritestat = cmd(R,R),
|
||||||
|
clipmove = cmd(W,W,W,R,W,R,R,R,R,R,R),
|
||||||
|
clipmovenoslide = cmd(W,W,W,R,W,R,R,R,R,R,R),
|
||||||
|
displayrand = cmd(W),
|
||||||
|
displayrandvar = cmd(W,D),
|
||||||
|
displayrandvarvar = cmd(W,R),
|
||||||
|
dist = cmd(W),
|
||||||
|
dragpoint = cmd(R,R,R),
|
||||||
|
hitscan = cmd(R,R,R,R,R,R,R,W,W,W,W,W,W,R), -- 7R 6W 1R
|
||||||
|
|
||||||
|
-- screen text and numbers display
|
||||||
|
gametext = cmd(R,R,R,R,R,R,R,R,R,R,R), -- 11 R
|
||||||
|
gametextz = cmd(R,R,R,R,R,R,R,R,R,R,R,R), -- 12 R
|
||||||
|
digitalnumber = cmd(R,R,R,R,R,R,R,R,R,R,R), -- 11R
|
||||||
|
digitalnumberz = cmd(W,R,R,R,R,R,R,R,R,R,R,R), -- 1W 11R
|
||||||
|
minitext = cmd(R,R,R,R,R),
|
||||||
|
|
||||||
|
ldist = cmd(W),
|
||||||
|
lineintersect = cmd(R,R,R,R,R,R,R,R,R,R,W,W,W,W), -- 10R 4W
|
||||||
|
rayintersect = cmd(R,R,R,R,R,R,R,R,R,R,W,W,W,W), -- 10R 4W
|
||||||
|
loadmapstate = cmd(),
|
||||||
|
savemapstate = cmd(),
|
||||||
|
movesprite = cmd(R,R,R,R,R,W),
|
||||||
|
neartag = cmd(R,R,R,R,R,W,W,W,W,R,R),
|
||||||
|
operateactivators = cmd(R),
|
||||||
|
operatesectors = cmd(R),
|
||||||
|
palfrom = (sp1 * t_define)^-4,
|
||||||
|
|
||||||
|
myos = cmd(R,R,R,R,R),
|
||||||
|
myospal = cmd(R,R,R,R,R,R),
|
||||||
|
myospalx = cmd(R,R,R,R,R,R),
|
||||||
|
myosx = cmd(R,R,R,R,R),
|
||||||
|
|
||||||
|
headspritesect = cmd(R,R),
|
||||||
|
headspritestat = cmd(R,R),
|
||||||
|
nextspritesect = cmd(R,R),
|
||||||
|
nextspritestat = cmd(R,R),
|
||||||
|
prevspritesect = cmd(R,R),
|
||||||
|
prevspritestat = cmd(R,R),
|
||||||
|
|
||||||
|
readarrayfromfile = cmd(I,D),
|
||||||
|
writearraytofile = cmd(I,D),
|
||||||
|
|
||||||
|
redefinequote = sp1 * t_define * newline_term_string,
|
||||||
|
resizearray = cmd(I,R),
|
||||||
|
getarraysize = cmd(I,W),
|
||||||
|
rotatepoint = cmd(R,R,R,R,R,W,W),
|
||||||
|
rotatesprite = cmd(R,R,R,R,R,R,R,R,R,R,R,R), -- 12R
|
||||||
|
rotatesprite16 = cmd(R,R,R,R,R,R,R,R,R,R,R,R), -- 12R
|
||||||
|
sectorofwall = cmd(W,R,R),
|
||||||
|
sectclearinterpolation = cmd(R),
|
||||||
|
sectsetinterpolation = cmd(R),
|
||||||
|
|
||||||
|
sectgethitag = cmd(),
|
||||||
|
sectgetlotag = cmd(),
|
||||||
|
spgethitag = cmd(),
|
||||||
|
spgetlotag = cmd(),
|
||||||
|
|
||||||
|
showview = cmd(R,R,R,R,R,R,R,R,R,R), -- 10R
|
||||||
|
showviewunbiased = cmd(R,R,R,R,R,R,R,R,R,R), -- 10R
|
||||||
|
smaxammo = cmd(R,R),
|
||||||
|
gmaxammo = cmd(R,W),
|
||||||
|
spriteflags = cmd(R), -- also see outer
|
||||||
|
ssp = cmd(R,R),
|
||||||
|
startlevel = cmd(R,R),
|
||||||
|
starttrack = cmd(D),
|
||||||
|
stopactorsound = cmd(R,R),
|
||||||
|
stopallsounds = cmd(),
|
||||||
|
updatesector = cmd(R,R,W),
|
||||||
|
updatesectorz = cmd(R,R,R,W),
|
||||||
|
|
||||||
|
getactorangle = cmd(W),
|
||||||
|
setactorangle = cmd(R),
|
||||||
|
getplayerangle = cmd(W),
|
||||||
|
setplayerangle = cmd(R),
|
||||||
|
getangletotarget = cmd(W),
|
||||||
|
|
||||||
|
getceilzofslope = cmd(R,R,R,W),
|
||||||
|
getflorzofslope = cmd(R,R,R,W),
|
||||||
|
getcurraddress = cmd(W), -- XXX
|
||||||
|
getkeyname = cmd(R,R,R),
|
||||||
|
getpname = cmd(R,R),
|
||||||
|
gettextureceiling = cmd(),
|
||||||
|
gettexturefloor = cmd(),
|
||||||
|
getticks = cmd(W),
|
||||||
|
gettimedate = cmd(W,W,W,W,W,W,W,W),
|
||||||
|
getzrange = cmd(R,R,R,R,W,W,W,W,R,R),
|
||||||
|
|
||||||
|
setactorsoundpitch = cmd(R,R,R),
|
||||||
|
setaspect = cmd(R,R),
|
||||||
|
}
|
||||||
|
|
||||||
|
local Cif = {
|
||||||
|
-- XXX: ai, action, move/def labels
|
||||||
|
ifai = cmd(D),
|
||||||
|
ifaction = cmd(D),
|
||||||
|
ifmove = cmd(D),
|
||||||
|
|
||||||
|
ifrnd = cmd(D),
|
||||||
|
ifpdistl = cmd(D),
|
||||||
|
ifpdistg = cmd(D),
|
||||||
|
ifwasweapon = cmd(D),
|
||||||
|
ifactioncount = cmd(D),
|
||||||
|
ifcount = cmd(D),
|
||||||
|
ifactor = cmd(D),
|
||||||
|
ifstrength = cmd(D),
|
||||||
|
ifspawnedby = cmd(D),
|
||||||
|
ifgapzl = cmd(D),
|
||||||
|
iffloordistl = cmd(D),
|
||||||
|
ifceilingdistl = cmd(D),
|
||||||
|
ifphealthl = cmd(D),
|
||||||
|
ifspritepal = cmd(D),
|
||||||
|
ifgotweaponce = cmd(D),
|
||||||
|
ifangdiffl = cmd(D),
|
||||||
|
ifsound = cmd(D),
|
||||||
|
ifpinventory = cmd(D,D),
|
||||||
|
|
||||||
|
ifp = (sp1 * t_define)^1,
|
||||||
|
|
||||||
|
ifclient = cmd(),
|
||||||
|
ifserver = cmd(),
|
||||||
|
ifonwater = cmd(),
|
||||||
|
ifinwater = cmd(),
|
||||||
|
ifactornotstayput = cmd(),
|
||||||
|
ifactorsound = cmd(),
|
||||||
|
ifcansee = cmd(),
|
||||||
|
ifhitweapon = cmd(),
|
||||||
|
ifsquished = cmd(),
|
||||||
|
ifdead = cmd(),
|
||||||
|
ifcanshoottarget = cmd(),
|
||||||
|
ifhitspace = cmd(),
|
||||||
|
ifoutside = cmd(),
|
||||||
|
ifmultiplayer = cmd(),
|
||||||
|
ifinspace = cmd(),
|
||||||
|
ifbulletnear = cmd(),
|
||||||
|
ifrespawn = cmd(),
|
||||||
|
ifinouterspace = cmd(),
|
||||||
|
ifnotmoving = cmd(),
|
||||||
|
ifawayfromwall = cmd(),
|
||||||
|
ifcanseetarget = cmd(),
|
||||||
|
ifnosounds = cmd(),
|
||||||
|
|
||||||
|
ifvarl = cmd(R,D),
|
||||||
|
ifvarg = cmd(R,D),
|
||||||
|
ifvare = cmd(R,D),
|
||||||
|
ifvarn = cmd(R,D),
|
||||||
|
ifvarand = cmd(R,D),
|
||||||
|
ifvaror = cmd(R,D),
|
||||||
|
ifvarxor = cmd(R,D),
|
||||||
|
ifvareither = cmd(R,D),
|
||||||
|
|
||||||
|
ifactorsound = cmd(R,R),
|
||||||
|
ifvarvarg = cmd(R,R),
|
||||||
|
ifvarvarl = cmd(R,R),
|
||||||
|
ifvarvare = cmd(R,R),
|
||||||
|
ifvarvarn = cmd(R,R),
|
||||||
|
ifvarvarand = cmd(R,R),
|
||||||
|
ifvarvaror = cmd(R,R),
|
||||||
|
ifvarvarxor = cmd(R,R),
|
||||||
|
ifvarvareither = cmd(R,R),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
-- A generic trace function, prints a position together with the match content
|
||||||
|
-- A non-existing 'doit' means 'true'.
|
||||||
|
function TraceFunc(pat, doit)
|
||||||
|
pat = Pat(pat)
|
||||||
|
|
||||||
|
if (doit==nil or doit) then
|
||||||
|
pat = lpeg.Cmt(pat, function (subj, pos, a) print(pos..":"..a); return true; end)
|
||||||
|
end
|
||||||
|
return pat
|
||||||
|
end
|
||||||
|
|
||||||
|
-- These are tracers for specific patterns which can be disabled
|
||||||
|
-- if desired.
|
||||||
|
local function Keyw(kwname) return TraceFunc(kwname, false) end
|
||||||
|
local function Stmt(cmdpat) return TraceFunc(cmdpat, false) end
|
||||||
|
|
||||||
|
|
||||||
|
-- attach the command names at the front!
|
||||||
|
function attachnames(kwtab)
|
||||||
|
for cmdname,cmdpat in pairs(kwtab) do
|
||||||
|
kwtab[cmdname] = Keyw(cmdname) * cmdpat
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
attachnames(Co)
|
||||||
|
attachnames(Ci)
|
||||||
|
attachnames(Cif)
|
||||||
|
|
||||||
|
|
||||||
|
-- Takes one or more tables and +'s all its patterns together in the order of
|
||||||
|
-- appearance.
|
||||||
|
-- The tables must map command names to their patterns.
|
||||||
|
function all_alt_pattern(...)
|
||||||
|
local pat = Pat(false)
|
||||||
|
local args = {...}
|
||||||
|
for argi=1,#args do
|
||||||
|
local pattab = args[argi]
|
||||||
|
for cmdname,cmdpat in pairs(pattab) do
|
||||||
|
pat = pat + cmdpat
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return pat
|
||||||
|
end
|
||||||
|
|
||||||
|
-- actor ORGANTIC is greeting!
|
||||||
|
local function warn_on_lonely_else(subj, pos)
|
||||||
|
print(pos..": warning: found `else' with no `if'")
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
-- About prefixes: I think it's not a problem if e.g. "getactor" comes before
|
||||||
|
-- "getactorvar", because the pattern for the former will fail eventually in
|
||||||
|
-- the ordered choice if fed with the latter.
|
||||||
|
local con_outer_command = all_alt_pattern(Co)
|
||||||
|
local con_inner_command = all_alt_pattern(Ci)
|
||||||
|
local con_if_begs = all_alt_pattern(Cif)
|
||||||
|
|
||||||
|
local lone_else = lpeg.Cmt("else" * sp1, warn_on_lonely_else)
|
||||||
|
|
||||||
|
local stmt_list = Var("stmt_list")
|
||||||
|
-- possibly empty statement list:
|
||||||
|
local stmt_list_or_eps = (stmt_list * sp1)^-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"
|
||||||
|
|
||||||
|
--== block delimiters (no recursion) ==--
|
||||||
|
local Cb = {
|
||||||
|
-- actor (...)
|
||||||
|
actor = common_actor_end,
|
||||||
|
-- eventloadactor (...)
|
||||||
|
eventloadactor = common_actor_end,
|
||||||
|
-- useractor <actortype> (...)
|
||||||
|
useractor = sp1 * t_define * common_actor_end,
|
||||||
|
|
||||||
|
onevent = sp1 * t_define * sp1 * stmt_list_or_eps * "endevent",
|
||||||
|
|
||||||
|
state = sp1 * t_identifier * sp1 * stmt_list_or_eps * "ends",
|
||||||
|
}
|
||||||
|
|
||||||
|
attachnames(Cb)
|
||||||
|
|
||||||
|
|
||||||
|
--- The final grammar!
|
||||||
|
local Grammar = Pat{
|
||||||
|
-- The starting symbol.
|
||||||
|
-- A translation unit is a (possibly empty) sequence of outer CON
|
||||||
|
-- commands, separated by at least one whitespace which may be
|
||||||
|
-- omitted at the EOF.
|
||||||
|
sp0 * ((con_outer_command + all_alt_pattern(Cb)) * (sp1 + (-1)))^0,
|
||||||
|
|
||||||
|
-- Deps. These appear here because we're hitting a limit with LPeg else:
|
||||||
|
-- http://lua-users.org/lists/lua-l/2008-11/msg00462.html
|
||||||
|
whitespace = Set(" \t\r") + newline + Set("(),;") + comment + linecomment,
|
||||||
|
|
||||||
|
t_identifier_all = Range("AZ", "az", "__") * Range("AZ", "az", "__", "09")^0,
|
||||||
|
-- NOTE: -con_keyword alone would be wrong, e.g. "state breakobject":
|
||||||
|
-- NOTE 2: The + "[" is so that stuff like
|
||||||
|
-- getactor[THISACTOR].x x
|
||||||
|
-- getactor[THISACTOR].y y
|
||||||
|
-- is parsed correctly. (Compared with this:)
|
||||||
|
-- getactor[THISACTOR].x x
|
||||||
|
-- getactor [THISACTOR].y y
|
||||||
|
-- This is in need of cleanup!
|
||||||
|
t_identifier = -(con_keyword * (sp1 + "[")) * t_identifier_all,
|
||||||
|
t_define = Pat("-")^-1 * sp0 * (t_identifier + t_number),
|
||||||
|
|
||||||
|
t_arrayexp = t_identifier * arraypat * memberpat^-1,
|
||||||
|
|
||||||
|
switch_stmt = Keyw("switch") * (sp1 * (Var("case") + Var("default")))^0 * sp1 * "endswitch",
|
||||||
|
case = Keyw("case") * sp1 * t_define * sp0 * Pat(":")^-1 * sp1 * stmt_list_or_eps * "break",
|
||||||
|
default = Keyw("default") * sp0 * Pat(":")^-1 * sp1 * stmt_list_or_eps * "break",
|
||||||
|
|
||||||
|
-- The "lone" if statement is tested first, so that a potential dangling "else" is
|
||||||
|
-- attached to the outermost possible "if", as done by CON
|
||||||
|
if_stmt = con_if_begs * sp1 * Var("single_stmt") * -(sp1 * Pat("else"))
|
||||||
|
+ con_if_begs * sp1 * Var("single_stmt") * sp1 * "else" * sp1 * Var("single_stmt"),
|
||||||
|
|
||||||
|
while_stmt = Keyw("whilevarvarn") * sp1 * t_rvar * sp1 * t_rvar * sp1 * Var("single_stmt")
|
||||||
|
+ Keyw("whilevarn") * sp1 * t_rvar * sp1 * t_define * sp1 * Var("single_stmt"),
|
||||||
|
|
||||||
|
-- TODO: some sp1 --> sp0?
|
||||||
|
single_stmt = Stmt(
|
||||||
|
lone_else^-1 *
|
||||||
|
( Keyw("{") * sp0 * "}"
|
||||||
|
+ Keyw("{") * sp1 * stmt_list * sp1 * "}"
|
||||||
|
+ (con_inner_command + Var("switch_stmt") + Var("if_stmt") + Var("while_stmt"))
|
||||||
|
-- + lpeg.Cmt(t_newline_term_str, function (subj, curpos) print("Error at "..curpos) end)
|
||||||
|
)),
|
||||||
|
|
||||||
|
-- a non-empty statement/command list
|
||||||
|
stmt_list = Var("single_stmt") * (sp1 * Var("single_stmt"))^0,
|
||||||
|
}
|
||||||
|
|
||||||
|
local math = require("math")
|
||||||
|
local string = require("string")
|
||||||
|
|
||||||
|
local function printf(fmt, ...)
|
||||||
|
print(string.format(fmt, ...))
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Returns index into the sorted table tab such that
|
||||||
|
-- tab[index] <= searchelt < tab[index+1].
|
||||||
|
-- Preconditions:
|
||||||
|
-- tab[i] < tab[i+1] for i < i+1 and 1 < i < #tab
|
||||||
|
-- tab[1] <= searchelt < tab[#tab]
|
||||||
|
-- If tab has less than 2 elements, returns nil.
|
||||||
|
local function bsearch(tab, searchelt)
|
||||||
|
-- printf("bsearch(tab, %d)", searchelt)
|
||||||
|
local l, r = 1, #tab
|
||||||
|
local i
|
||||||
|
|
||||||
|
if (r <= 1) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
while (l ~= r) do
|
||||||
|
i = l + math.ceil((r-l)/2) -- l < i <= r
|
||||||
|
assert(l < i and i <= r)
|
||||||
|
local elt = tab[i]
|
||||||
|
-- printf("l=%d tab[%d]=%d r=%d", l, i, elt, r)
|
||||||
|
|
||||||
|
if (searchelt == elt) then
|
||||||
|
return i
|
||||||
|
end
|
||||||
|
|
||||||
|
if (searchelt < elt) then
|
||||||
|
r = i-1
|
||||||
|
else -- (searchelt > elt)
|
||||||
|
l = i
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- printf("return tab[%d]=%d", l, tab[l])
|
||||||
|
return l
|
||||||
|
end
|
||||||
|
|
||||||
|
---=== stand-alone: ===---
|
||||||
|
if (not EDUKE32_LUNATIC) then
|
||||||
|
local io = require("io")
|
||||||
|
|
||||||
|
local filename = arg[1]
|
||||||
|
assert(filename)
|
||||||
|
|
||||||
|
local contents = io.open(filename):read("*all")
|
||||||
|
local idx = lpeg.match(Grammar, contents)
|
||||||
|
|
||||||
|
-- newlineidxs will contain the 1-based file offsets to "\n" characters
|
||||||
|
local newlineidxs = {}
|
||||||
|
for i in string.gmatch(contents, "()\n") do
|
||||||
|
newlineidxs[#newlineidxs+1] = i
|
||||||
|
end
|
||||||
|
newlineidxs[#newlineidxs+1] = #contents+1 -- dummy newline
|
||||||
|
|
||||||
|
if (not idx) then
|
||||||
|
print("Match failed.")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if (idx == #contents+1) then
|
||||||
|
print("Matched whole contents.")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
printf("Match succeeded up to %d (len=%d)", idx, #contents)
|
||||||
|
|
||||||
|
local i = bsearch(newlineidxs, idx)
|
||||||
|
local bi, ei = newlineidxs[i]+1, newlineidxs[i+1]-1
|
||||||
|
printf("Line goes from %d to %d", bi, ei)
|
||||||
|
print(string.sub(contents, bi, ei))
|
||||||
|
end
|
Loading…
Reference in a new issue