Lunatic translator improvements.

git-svn-id: https://svn.eduke32.com/eduke32@2612 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2012-04-22 19:10:46 +00:00
parent 6d9411f669
commit cb8e0d1b57
2 changed files with 468 additions and 433 deletions

View file

@ -2,369 +2,376 @@
-- require("lpeg") -- require("lpeg")
-- con_keyword = dofile("con_lang.lua") -- con_keyword = dofile("con_lang.lua")
-- NOTE: These MUST be in reverse lexicographical order!
-- Per CON syntax, valid identifiers names are disjunct from keywords,
-- so that a rule like
-- t_identifier = -con_keyword * (sp1 + "[") * t_identifier_all
-- (from the final grammar in lunacon.lua) must match the longest
-- possible keyword name, else the negation might wrongly not fail.
return return
lpeg.P(false) + 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" + "zshootvar" +
"zshoot" +
"xorvarvar" +
"xorvar" +
"writearraytofile" +
"whilevarvarn" +
"whilevarn" +
"wackplayer" +
"userquote" +
"useractor" +
"updatesectorz" +
"updatesector" +
"tossweapon" +
"tip" +
"time" +
"switch" +
"subvarvar" +
"subvar" +
"strength" +
"stopsoundvar" +
"stopsound" +
"stopallsounds" +
"stopactorsound" +
"state" +
"starttrackvar" +
"starttrack" +
"startlevel" +
"ssp" +
"sqrt" +
"spriteshadow" +
"spritepal" +
"spritenvg" +
"spritenoshade" +
"spritenopal" +
"spriteflags" +
"spgetlotag" +
"spgethitag" +
"spawn" +
"soundvar" +
"soundoncevar" +
"soundonce" +
"sound" +
"smaxammo" +
"sleeptime" +
"sizeto" +
"sizeat" +
"sin" +
"showviewunbiased" +
"showview" +
"shootvar" +
"shoot" +
"shiftvarr" +
"shiftvarl" +
"setwall" +
"setvarvar" +
"setvar" +
"setuserdef" +
"settspr" +
"setthisprojectile" +
"setsprite" +
"setsector" +
"setprojectile" +
"setplayervar" +
"setplayerangle" +
"setplayer" +
"setinput" +
"setgamepalette" +
"setgamename" +
"setdefname" +
"setcfgname" +
"setaspect" +
"setarray" +
"setactorvar" +
"setactorsoundpitch" +
"setactorangle" +
"setactor" +
"sectsetinterpolation" +
"sectorofwall" +
"sectgetlotag" +
"sectgethitag" +
"sectclearinterpolation" +
"scriptsize" +
"savenn" +
"savemapstate" +
"savegamevar" +
"save" +
"rotatesprite16" +
"rotatesprite" +
"rotatepoint" +
"return" +
"respawnhitag" +
"resizearray" +
"resetplayer" +
"resetcount" +
"resetactioncount" +
"redefinequote" +
"readgamevar" +
"readarrayfromfile" +
"rayintersect" +
"randvarvar" +
"randvar" +
"quote" +
"quake" +
"qsubstr" +
"qstrncat" +
"qstrlen" +
"qstrcpy" +
"qstrcat" +
"qsprintf" +
"qspawnvar" +
"qspawn" +
"qgetsysstr" +
"pstomp" +
"prevspritestat" +
"prevspritesect" +
"precache" +
"pkick" +
"paper" +
"palfrom" +
"orvarvar" +
"orvar" +
"operatesectors" +
"operaterespawns" +
"operatemasterswitches" +
"operateactivators" +
"operate" +
"onevent" +
"nullop" +
"nextspritestat" +
"nextspritesect" +
"neartag" +
"myosx" +
"myospalx" +
"myospal" +
"myos" +
"music" +
"mulvarvar" +
"mulvar" +
"mulscale" +
"movesprite" +
"move" +
"money" +
"modvarvar" +
"modvar" +
"minitext" +
"mikesnd" +
"mail" +
"lotsofglass" +
"lockplayer" +
"loadmapstate" +
"lineintersect" +
"ldist" +
"killit" +
"jump" +
"insertspriteq" +
"inittimer" +
"includedefault" +
"include" +
"ifwasweapon" +
"ifvarxor" +
"ifvarvarxor" +
"ifvarvaror" +
"ifvarvarn" +
"ifvarvarl" +
"ifvarvarg" +
"ifvarvareither" +
"ifvarvare" +
"ifvarvarand" +
"ifvaror" +
"ifvarn" +
"ifvarl" +
"ifvarg" +
"ifvareither" +
"ifvare" +
"ifvarand" +
"ifstrength" +
"ifsquished" +
"ifspritepal" +
"ifspawnedby" +
"ifsound" +
"ifserver" +
"ifrnd" +
"ifrespawn" +
"ifpinventory" +
"ifphealthl" +
"ifpdistl" +
"ifpdistg" +
"ifp" +
"ifoutside" +
"ifonwater" +
"ifnotmoving" +
"ifnosounds" +
"ifmultiplayer" +
"ifmove" +
"ifinwater" +
"ifinspace" +
"ifinouterspace" +
"ifhitweapon" +
"ifhitspace" +
"ifgotweaponce" +
"ifgapzl" +
"iffloordistl" +
"ifdead" +
"ifcount" +
"ifclient" +
"ifceilingdistl" +
"ifcanshoottarget" +
"ifcanseetarget" +
"ifcansee" +
"ifbulletnear" +
"ifawayfromwall" +
"ifangdiffl" +
"ifai" +
"ifactorsound" +
"ifactornotstayput" +
"ifactor" +
"ifactioncount" +
"ifaction" +
"hitscan" +
"hitradiusvar" +
"hitradius" +
"headspritestat" +
"headspritesect" +
"guts" +
"guniqhudid" +
"gmaxammo" +
"globalsoundvar" +
"globalsound" +
"getzrange" +
"getwall" +
"getuserdef" +
"gettspr" +
"gettimedate" +
"getticks" +
"getthisprojectile" +
"gettexturefloor" +
"gettextureceiling" +
"getsector" +
"getprojectile" +
"getpname" +
"getplayervar" +
"getplayerangle" +
"getplayer" +
"getlastpal" +
"getkeyname" +
"getinput" +
"getincangle" +
"getflorzofslope" +
"getcurraddress" +
"getceilzofslope" +
"getarraysize" +
"getangletotarget" +
"getangle" +
"getactorvar" +
"getactorangle" +
"getactor" +
"gamevar" +
"gametextz" +
"gametext" +
"gamestartup" +
"gamearray" +
"flash" +
"findplayer" +
"findotherplayer" +
"findnearspritezvar" +
"findnearspritez" +
"findnearspritevar" +
"findnearsprite3dvar" +
"findnearsprite3d" +
"findnearsprite" +
"findnearactorzvar" +
"findnearactorz" +
"findnearactorvar" +
"findnearactor3dvar" +
"findnearactor3d" +
"findnearactor" +
"fall" +
"ezshootvar" +
"ezshoot" +
"eventloadactor" +
"espawnvar" +
"espawn" +
"eshootvar" +
"eshoot" +
"eqspawnvar" +
"eqspawn" +
"enhanced" +
"endswitch" +
"ends" +
"endofgame" +
"endevent" +
"enda" +
"else" +
"echo" +
"dynamicremap" +
"dragpoint" +
"divvarvar" +
"divvar" +
"dist" +
"displayrandvarvar" +
"displayrandvar" +
"displayrand" +
"digitalnumberz" +
"digitalnumber" +
"definevolumename" +
"definesound" +
"defineskillname" +
"definequote" +
"defineprojectile" +
"definelevelname" +
"definegametype" +
"definegamefuncname" +
"definecheat" +
"define" +
"default" +
"debug" +
"debris" +
"cstator" +
"cstat" +
"count" +
"cos" +
"copy" +
"cmenu" +
"clipmovenoslide" +
"clipmove" +
"clipdist" +
"clearmapstate" +
"checkavailweapon" +
"checkavailinven" +
"checkactivatormotion" +
"cheatkeys" +
"changespritestat" +
"changespritesect" +
"case" +
"canseespr" +
"cansee" +
"calchypotenuse" +
"cactor" +
"break" +
"betaname" +
"angoffvar" +
"angoff" +
"andvarvar" +
"andvar" +
"ai" +
"addweaponvar" +
"addweapon" +
"addvarvar" +
"addvar" +
"addstrength" +
"addphealth" +
"addlogvar" +
"addlog" +
"addkills" +
"addinventory" +
"addammo" +
"actor" +
"activatecheat" +
"activatebysector" +
"action" +
lpeg.P(false) lpeg.P(false)

View file

@ -160,7 +160,6 @@ local Co = {
--== Run time CON commands ==-- --== Run time CON commands ==--
--- 1. Gamevar Operators --- 1. Gamevar Operators
local varop = cmd(W,D) local varop = cmd(W,D)
local varvarop = cmd(W,R) local varvarop = cmd(W,R)
@ -168,18 +167,20 @@ local varvarop = cmd(W,R)
local arraypat = sp0 * "[" * sp0 * t_define * sp0 * "]" local arraypat = sp0 * "[" * sp0 * t_define * sp0 * "]"
-- 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[]
-- XXX: actor and sprite members can have parm2, e.g. this is legal:
-- ifvare player[THISACTOR].gotweapon 4 0
-- but not parsed currently.
local memberpat = sp0 * "." * sp0 * t_identifier_all local memberpat = sp0 * "." * sp0 * t_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 -- existence of a second parameter is determined later
-- This is wrong, (sp1 id)? will match (sp1 wvar) if there's no 2nd param: -- This is wrong, (sp1 id)? will match (sp1 wvar) if there's no 2nd param:
-- arraypat * memberpat * (sp1 * t_identifier)^-1 * sp1 * t_wvar -- arraypat * memberpat * (sp1 * t_identifier)^-1 * sp1 * t_wvar
-- XXX: This is still wrong. arraypat * memberpat * sp1 * (t_rvar * sp1 * t_wvar + t_wvar)
arraypat * memberpat * sp1 * (t_identifier * sp1 * t_wvar + t_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 -- existence of a second parameter is determined later
arraypat * memberpat * sp1 * (t_identifier * sp1 * t_rvar + t_rvar) arraypat * memberpat * sp1 * (t_rvar * sp1 * t_rvar + t_rvar)
local getperxvarcmd = -- get<actor/player>var[<idx>].<member> <<var>> local getperxvarcmd = -- get<actor/player>var[<idx>].<member> <<var>>
arraypat * memberpat * sp1 * t_wvar arraypat * memberpat * sp1 * t_wvar
@ -201,7 +202,6 @@ local Ci = {
getplayer = getstructcmd, getplayer = getstructcmd,
getprojectile = getstructcmd, getprojectile = getstructcmd,
getsector = getstructcmd, getsector = getstructcmd,
getsprite = getstructcmd,
getthisprojectile = getstructcmd, getthisprojectile = getstructcmd,
gettspr = getstructcmd, gettspr = getstructcmd,
getuserdef = getstructcmd, getuserdef = getstructcmd,
@ -215,7 +215,6 @@ local Ci = {
setplayer = setstructcmd, setplayer = setstructcmd,
setprojectile = setstructcmd, setprojectile = setstructcmd,
setsector = setstructcmd, setsector = setstructcmd,
setsprite = setstructcmd,
setthisprojectile = setstructcmd, setthisprojectile = setstructcmd,
settspr = setstructcmd, settspr = setstructcmd,
setuserdef = setstructcmd, setuserdef = setstructcmd,
@ -224,6 +223,8 @@ local Ci = {
setactorvar = setperxvarcmd, setactorvar = setperxvarcmd,
setplayervar = setperxvarcmd, setplayervar = setperxvarcmd,
setsprite = cmd(R,R,R,R),
setvarvar = varvarop, setvarvar = varvarop,
addvarvar = varvarop, addvarvar = varvarop,
subvarvar = varvarop, subvarvar = varvarop,
@ -253,7 +254,7 @@ local Ci = {
calchypotenuse = cmd(W,R,R), calchypotenuse = cmd(W,R,R),
sin = cmd(W,R), sin = cmd(W,R),
cos = cmd(W,R), cos = cmd(W,R),
mulscale = cmd(W,R,R), mulscale = cmd(W,R,R,R),
getangle = cmd(W,R,R), getangle = cmd(W,R,R),
getincangle = cmd(W,R,R), getincangle = cmd(W,R,R),
@ -365,20 +366,20 @@ local Ci = {
tossweapon = cmd(), tossweapon = cmd(),
wackplayer = cmd(), wackplayer = cmd(),
-- sprite searching -- player/sprite searching
findplayer = cmd(D,D), findplayer = cmd(W),
findotherplayer = cmd(D,D), findotherplayer = cmd(W),
findnearspritezvar = cmd(D,R,R,W), findnearspritezvar = cmd(D,R,R,W),
findnearspritez = cmd(D,D,D,W), findnearspritez = cmd(D,D,D,W),
findnearspritevar = cmd(D,R,W),
findnearsprite3dvar = cmd(D,R,W), findnearsprite3dvar = cmd(D,R,W),
findnearsprite3d = cmd(D,D,W), findnearsprite3d = cmd(D,D,W),
findnearspritevar = cmd(D,R,W),
findnearsprite = cmd(D,D,W), findnearsprite = cmd(D,D,W),
findnearactorzvar = cmd(D,R,R,W), findnearactorzvar = cmd(D,R,R,W),
findnearactorz = cmd(D,D,D,W), findnearactorz = cmd(D,D,D,W),
findnearactorvar = cmd(D,R,W),
findnearactor3dvar = cmd(D,R,W), findnearactor3dvar = cmd(D,R,W),
findnearactor3d = cmd(D,D,W), findnearactor3d = cmd(D,D,W),
findnearactorvar = cmd(D,R,W),
findnearactor = cmd(D,D,W), findnearactor = cmd(D,D,W),
-- quotes -- quotes
@ -407,7 +408,7 @@ local Ci = {
displayrand = cmd(W), displayrand = cmd(W),
displayrandvar = cmd(W,D), displayrandvar = cmd(W,D),
displayrandvarvar = cmd(W,R), displayrandvarvar = cmd(W,R),
dist = cmd(W), dist = cmd(W,R,R),
dragpoint = cmd(R,R,R), dragpoint = cmd(R,R,R),
hitscan = cmd(R,R,R,R,R,R,R,W,W,W,W,W,W,R), -- 7R 6W 1R hitscan = cmd(R,R,R,R,R,R,R,W,W,W,W,W,W,R), -- 7R 6W 1R
@ -418,7 +419,7 @@ local Ci = {
digitalnumberz = cmd(W,R,R,R,R,R,R,R,R,R,R,R), -- 1W 11R digitalnumberz = cmd(W,R,R,R,R,R,R,R,R,R,R,R), -- 1W 11R
minitext = cmd(R,R,R,R,R), minitext = cmd(R,R,R,R,R),
ldist = cmd(W), ldist = cmd(W,R,R),
lineintersect = cmd(R,R,R,R,R,R,R,R,R,R,W,W,W,W), -- 10R 4W 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 rayintersect = cmd(R,R,R,R,R,R,R,R,R,R,W,W,W,W), -- 10R 4W
loadmapstate = cmd(), loadmapstate = cmd(),
@ -564,25 +565,85 @@ local Cif = {
} }
----==== Tracing and reporting ====----
local string = require("string")
-- newlineidxs will contain the 1-based file offsets to "\n" characters
local newlineidxs = {}
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 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
local function getlinecol(pos)
local line = bsearch(newlineidxs, pos)
local col = pos-newlineidxs[line]
return line, col
end
-- A generic trace function, prints a position together with the match content -- A generic trace function, prints a position together with the match content
-- A non-existing 'doit' means 'true'. -- A non-existing 'doit' means 'true'.
function TraceFunc(pat, doit) local function TraceFunc(pat, label, doit)
pat = Pat(pat) pat = Pat(pat)
if (doit==nil or doit) then if (doit==nil or doit) then
pat = lpeg.Cmt(pat, function (subj, pos, a) print(pos..":"..a); return true; end) local function tfunc(subj, pos, a)
local line, col = getlinecol(pos)
printf("%d,%d:%s:%s", line, col, label, a)
return true
end
pat = lpeg.Cmt(pat, tfunc)
end end
return pat return pat
end end
-- These are tracers for specific patterns which can be disabled -- These are tracers for specific patterns which can be disabled
-- if desired. -- if desired.
local function Keyw(kwname) return TraceFunc(kwname, false) end local function Keyw(kwname) return TraceFunc(kwname, "kw", true) end
local function Stmt(cmdpat) return TraceFunc(cmdpat, false) end local function NotKeyw(text) return TraceFunc(text, "!kw", true) end
local function Ident(idname) return TraceFunc(idname, "id", true) end
local function Stmt(cmdpat) return TraceFunc(cmdpat, "st", true) end
----==== Translator continued ====----
-- attach the command names at the front! -- attach the command names at the front!
function attachnames(kwtab) local function attachnames(kwtab)
for cmdname,cmdpat in pairs(kwtab) do for cmdname,cmdpat in pairs(kwtab) do
kwtab[cmdname] = Keyw(cmdname) * cmdpat kwtab[cmdname] = Keyw(cmdname) * cmdpat
end end
@ -596,7 +657,7 @@ attachnames(Cif)
-- Takes one or more tables and +'s all its patterns together in the order of -- Takes one or more tables and +'s all its patterns together in the order of
-- appearance. -- appearance.
-- The tables must map command names to their patterns. -- The tables must map command names to their patterns.
function all_alt_pattern(...) local function all_alt_pattern(...)
local pat = Pat(false) local pat = Pat(false)
local args = {...} local args = {...}
for argi=1,#args do for argi=1,#args do
@ -614,9 +675,11 @@ local function warn_on_lonely_else(subj, pos)
return true return true
end end
-- About prefixes: I think it's not a problem if e.g. "getactor" comes before -- About prefixes: I think it's not a problem *here* if e.g. "getactor" comes
-- "getactorvar", because the pattern for the former will fail eventually in -- before "getactorvar", because the pattern for the former will fail
-- the ordered choice if fed with the latter. -- eventually in the ordered choice if fed with the latter. However, it DOES
-- matter in the keyword list, see NotKeyw() trace function and comment in
-- con_lang.lua.
local con_outer_command = all_alt_pattern(Co) local con_outer_command = all_alt_pattern(Co)
local con_inner_command = all_alt_pattern(Ci) local con_inner_command = all_alt_pattern(Ci)
local con_if_begs = all_alt_pattern(Cif) local con_if_begs = all_alt_pattern(Cif)
@ -668,7 +731,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 = -(con_keyword * (sp1 + "[")) * t_identifier_all, t_identifier = -NotKeyw(con_keyword * (sp1 + "[")) * Ident(t_identifier_all),
t_define = Pat("-")^-1 * sp0 * (t_identifier + t_number), t_define = Pat("-")^-1 * sp0 * (t_identifier + t_number),
t_arrayexp = t_identifier * arraypat * memberpat^-1, t_arrayexp = t_identifier * arraypat * memberpat^-1,
@ -698,47 +761,15 @@ local Grammar = Pat{
stmt_list = Var("single_stmt") * (sp1 * Var("single_stmt"))^0, stmt_list = Var("single_stmt") * (sp1 * Var("single_stmt"))^0,
} }
local math = require("math") local math = require("math")
local string = require("string")
local function printf(fmt, ...) local function setup_newlineidxs(contents)
print(string.format(fmt, ...)) newlineidxs = {}
end for i in string.gmatch(contents, "()\n") do
newlineidxs[#newlineidxs+1] = i
-- Returns index into the sorted table tab such that
-- tab[index] <= searchelt < tab[index+1].
-- Preconditions:
-- tab[i] < tab[i+1] for 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 end
newlineidxs[#newlineidxs+1] = #contents+1 -- dummy newline
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 end
---=== stand-alone: ===--- ---=== stand-alone: ===---
@ -749,14 +780,9 @@ if (not EDUKE32_LUNATIC) then
assert(filename) assert(filename)
local contents = io.open(filename):read("*all") local contents = io.open(filename):read("*all")
local idx = lpeg.match(Grammar, contents) setup_newlineidxs(contents)
-- newlineidxs will contain the 1-based file offsets to "\n" characters local idx = lpeg.match(Grammar, contents)
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 if (not idx) then
print("Match failed.") print("Match failed.")
@ -768,10 +794,12 @@ if (not EDUKE32_LUNATIC) then
return return
end end
printf("Match succeeded up to %d (len=%d)", idx, #contents) local i, col = getlinecol(idx)
local i = bsearch(newlineidxs, idx)
local bi, ei = newlineidxs[i]+1, newlineidxs[i+1]-1 local bi, ei = newlineidxs[i]+1, newlineidxs[i+1]-1
printf("Line goes from %d to %d", bi, ei)
printf("Match succeeded up to %d (line %d, col %d; len=%d)",
idx, i, col, #contents)
-- printf("Line goes from %d to %d", bi, ei)
print(string.sub(contents, bi, ei)) print(string.sub(contents, bi, ei))
end end