mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-11-11 07:11:39 +00:00
Lunatic translator: fix dangling else and add a test file, tweak warnings
git-svn-id: https://svn.eduke32.com/eduke32@2756 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
parent
ec56b8e2d9
commit
f2789ab90f
2 changed files with 52 additions and 16 deletions
|
@ -42,9 +42,13 @@ local g_lastkw = nil
|
||||||
local g_badids = {} -- maps bad id strings to 'true'
|
local g_badids = {} -- maps bad id strings to 'true'
|
||||||
|
|
||||||
local g_recurslevel = -1 -- 0: base CON file, >0 included
|
local g_recurslevel = -1 -- 0: base CON file, >0 included
|
||||||
|
local g_filename = "???"
|
||||||
local g_directory = "" -- with trailing slash if not empty
|
local g_directory = "" -- with trailing slash if not empty
|
||||||
local g_numerrors = 0
|
local g_numerrors = 0
|
||||||
|
|
||||||
|
local g_ifnestlevel = 0 -- needed to cope with CONs dangling-else resolution
|
||||||
|
|
||||||
|
|
||||||
local function getlinecol(pos) end -- fwd-decl
|
local function getlinecol(pos) end -- fwd-decl
|
||||||
|
|
||||||
local function linecolstr(pos)
|
local function linecolstr(pos)
|
||||||
|
@ -54,24 +58,30 @@ end
|
||||||
|
|
||||||
local function errprintf(fmt, ...)
|
local function errprintf(fmt, ...)
|
||||||
if (g_lastkwpos) then
|
if (g_lastkwpos) then
|
||||||
printf("%s: error: "..fmt, linecolstr(g_lastkwpos), ...)
|
printf("%s %s: error: "..fmt, g_filename, linecolstr(g_lastkwpos), ...)
|
||||||
else
|
else
|
||||||
printf("???: error: "..fmt, ...)
|
printf("%s ???: error: "..fmt, g_filename, ...)
|
||||||
end
|
end
|
||||||
g_numerrors = g_numerrors+1
|
g_numerrors = g_numerrors+1
|
||||||
end
|
end
|
||||||
|
|
||||||
local function parse_number(numstr, pos)
|
local function warnprintf(fmt, ...)
|
||||||
|
if (g_lastkwpos) then
|
||||||
|
printf("%s %s: warning: "..fmt, g_filename, linecolstr(g_lastkwpos), ...)
|
||||||
|
else
|
||||||
|
printf("%s ???: warning: "..fmt, g_filename, ...)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function parse_number(numstr)
|
||||||
local num = tonumber(numstr)
|
local num = tonumber(numstr)
|
||||||
|
|
||||||
-- TODO: print line number
|
-- TODO: print line number
|
||||||
if (num < -0x80000000 or num > 0xffffffff) then
|
if (num < -0x80000000 or num > 0xffffffff) then
|
||||||
printf("%s: warning: number %s out of the range of a 32-bit integer",
|
errprintf("number %s out of the range of a 32-bit integer", numstr)
|
||||||
linecolstr(g_lastkwpos), numstr)
|
|
||||||
num = 0/0
|
num = 0/0
|
||||||
elseif (num >= 0x80000000) then
|
elseif (num >= 0x80000000 and numstr:sub(1,2):lower()~="0x") then
|
||||||
printf("%s: warning: number %s converted to a negative one",
|
warnprintf("number %s converted to a negative one", numstr)
|
||||||
linecolstr(g_lastkwpos), numstr)
|
|
||||||
num = num-0x100000000
|
num = num-0x100000000
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -126,8 +136,8 @@ local function do_define_label(identifier, idornum)
|
||||||
local oldnum = g_labeldef[identifier]
|
local oldnum = g_labeldef[identifier]
|
||||||
if (oldnum) then
|
if (oldnum) then
|
||||||
if (oldnum ~= num) then
|
if (oldnum ~= num) then
|
||||||
errprintf("label \"%s\" defined with different value (old: %d, new: %d)",
|
warnprintf("label \"%s\" not redefined with new value %d (old: %d)",
|
||||||
identifier, oldnum, num)
|
identifier, num, oldnum)
|
||||||
end
|
end
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
@ -173,7 +183,10 @@ else
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local oldfilename = g_filename
|
||||||
|
g_filename = filename
|
||||||
parse(contents)
|
parse(contents)
|
||||||
|
g_filename = oldfilename
|
||||||
end
|
end
|
||||||
|
|
||||||
function cmd_include(filename)
|
function cmd_include(filename)
|
||||||
|
@ -833,7 +846,7 @@ end
|
||||||
local function BadIdent(pat)
|
local function BadIdent(pat)
|
||||||
local function tfunc(subj, pos, a)
|
local function tfunc(subj, pos, a)
|
||||||
if (not g_badids[a]) then
|
if (not g_badids[a]) then
|
||||||
printf("%s: warning: bad identifier: %s", linecolstr(pos), a)
|
warnprintf("bad identifier: %s", a)
|
||||||
g_badids[a] = true
|
g_badids[a] = true
|
||||||
end
|
end
|
||||||
return true
|
return true
|
||||||
|
@ -895,7 +908,7 @@ end
|
||||||
|
|
||||||
-- actor ORGANTIC is greeting!
|
-- actor ORGANTIC is greeting!
|
||||||
local function warn_on_lonely_else(subj, pos)
|
local function warn_on_lonely_else(subj, pos)
|
||||||
printf("%s: warning: found `else' with no `if'", linecolstr(pos))
|
warnprintf("found `else' with no `if'")
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -953,6 +966,18 @@ local t_good_identifier = Range("AZ", "az", "__") * Range("AZ", "az", "__", "09"
|
||||||
local t_broken_identifier = BadIdent(-((t_number + t_good_identifier) * (sp1 + Set("[]:"))) *
|
local t_broken_identifier = BadIdent(-((t_number + t_good_identifier) * (sp1 + Set("[]:"))) *
|
||||||
(alphanum + Set("_/\\*")) * (alphanum + Set("_/\\*-"))^0)
|
(alphanum + Set("_/\\*")) * (alphanum + Set("_/\\*-"))^0)
|
||||||
|
|
||||||
|
local function begin_if_fn()
|
||||||
|
g_ifnestlevel = g_ifnestlevel+1
|
||||||
|
end
|
||||||
|
|
||||||
|
local function end_if_fn()
|
||||||
|
g_ifnestlevel = g_ifnestlevel-1
|
||||||
|
end
|
||||||
|
|
||||||
|
local function check_else_Cmt()
|
||||||
|
return (g_ifnestlevel==0) -- match an 'else' only at the outermost level
|
||||||
|
end
|
||||||
|
|
||||||
--- The final grammar!
|
--- The final grammar!
|
||||||
local Grammar = Pat{
|
local Grammar = Pat{
|
||||||
-- The starting symbol.
|
-- The starting symbol.
|
||||||
|
@ -992,11 +1017,10 @@ local Grammar = Pat{
|
||||||
|
|
||||||
default_block = sp1 * Keyw("default") * (sp0*":"*sp0 + sp1) * stmt_list_nosp_or_eps, -- * "break",
|
default_block = sp1 * Keyw("default") * (sp0*":"*sp0 + sp1) * stmt_list_nosp_or_eps, -- * "break",
|
||||||
|
|
||||||
-- The "lone" if statement is tested first, so that a potential dangling "else" is
|
if_stmt = con_if_begs/begin_if_fn * sp1 * Var("single_stmt") * Pat("")/end_if_fn
|
||||||
-- attached to the outermost possible "if", as done by CON
|
* (sp1 * lpeg.Cmt(Pat("else"), check_else_Cmt) * sp1 * Var("single_stmt"))^-1,
|
||||||
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"),
|
|
||||||
|
|
||||||
|
-- TODO?: SST TC has "state ... else ends"
|
||||||
while_stmt = Keyw("whilevarvarn") * sp1 * t_rvar * sp1 * t_rvar * 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"),
|
+ Keyw("whilevarn") * sp1 * t_rvar * sp1 * t_define * sp1 * Var("single_stmt"),
|
||||||
|
|
||||||
|
@ -1043,6 +1067,8 @@ function parse(contents) -- local
|
||||||
local lastkw, lastkwpos, numerrors = g_lastkw, g_lastkwpos, g_numerrors
|
local lastkw, lastkwpos, numerrors = g_lastkw, g_lastkwpos, g_numerrors
|
||||||
local newlineidxs = g_newlineidxs
|
local newlineidxs = g_newlineidxs
|
||||||
|
|
||||||
|
g_ifnestlevel = 0
|
||||||
|
|
||||||
-- set up new state
|
-- set up new state
|
||||||
-- TODO: pack into one "parser state" table?
|
-- TODO: pack into one "parser state" table?
|
||||||
g_lastkw, g_lastkwpos, g_numerrors = nil, nil, 0
|
g_lastkw, g_lastkwpos, g_numerrors = nil, nil, 0
|
||||||
|
|
10
polymer/eduke32/source/lunatic/test/dangling_else.con
Normal file
10
polymer/eduke32/source/lunatic/test/dangling_else.con
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
// a dangling 'else' in CON attaches to the outermost matching 'if'
|
||||||
|
onevent EVENT_INIT
|
||||||
|
redefinequote 114 DANGLING ELSE CHECK FAILED 1
|
||||||
|
ifvare 0 1
|
||||||
|
ifvare 0 0 redefinequote 114 DANGLING ELSE CHECK FAILED 2
|
||||||
|
else
|
||||||
|
redefinequote 114 DANGLING ELSE CHECK PASSED
|
||||||
|
|
||||||
|
echo 114
|
||||||
|
endevent
|
Loading…
Reference in a new issue