Lunatic: take a stab at semantic actions; tweaks

git-svn-id: https://svn.eduke32.com/eduke32@2748 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2012-06-10 18:56:18 +00:00
parent 59df76f0b6
commit 5531888c8b

View file

@ -26,6 +26,30 @@ local function match_until(matchsp, untilsp) -- (!untilsp matchsp)* in PEG
return (matchsp - Pat(untilsp))^0 return (matchsp - Pat(untilsp))^0
end end
local function printf(fmt, ...)
print(string.format(fmt, ...))
end
---=== semantic action functions ===---
local function getlinecol(pos) end -- fwd-decl
local function parse_number(numstr, pos)
local num = tonumber(numstr)
-- TODO: print line number
if (num < -0x80000000 or num > 0xffffffff) then
printf("warning: number %s out of the range of a 32-bit integer", numstr)
num = 0/0
elseif (num >= 0x80000000) then
printf("warning: number %s converted to a negative one", numstr)
num = num-0x100000000
end
return num
end
----==== patterns ====---- ----==== patterns ====----
@ -47,7 +71,10 @@ local alphanum = alpha + Range("09")
--local alnumtok = alphanum + Set("{}/\\*-_.") -- see isaltok() in gamedef.c --local alnumtok = alphanum + Set("{}/\\*-_.") -- see isaltok() in gamedef.c
--- basic lexical elements ("tokens") --- basic lexical elements ("tokens")
local t_number = (Pat("0x") + "0X")*Range("09", "af", "AF")^1 + Range("09")^1 local t_maybe_minus = (Pat("-") * sp0)^-1;
local t_number = lpeg.C(
t_maybe_minus * ((Pat("0x") + "0X")*Range("09", "af", "AF")^1 + Range("09")^1)
) / parse_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:
local t_identifier = Var("t_identifier") local t_identifier = Var("t_identifier")
@ -601,20 +628,16 @@ local string = require("string")
-- newlineidxs will contain the 1-based file offsets to "\n" characters -- newlineidxs will contain the 1-based file offsets to "\n" characters
local newlineidxs = {} local newlineidxs = {}
local function printf(fmt, ...)
print(string.format(fmt, ...))
end
-- Returns index into the sorted table tab such that -- Returns index into the sorted table tab such that
-- tab[index] <= searchelt < tab[index+1]. -- tab[index] <= searchelt < tab[index+1].
-- Preconditions: -- Preconditions:
-- tab[i] < tab[i+1] for 1 <= i < #tab -- tab[i] < tab[i+1] for 0 <= i < #tab
-- tab[1] <= searchelt < tab[#tab] -- tab[0] <= searchelt < tab[#tab]
-- If #tab is less than 2, returns 0. This plays nicely with newline index -- If #tab is less than 2, returns 0. This plays nicely with newline index
-- tables like { [0]=0, [1]=len+1 }, e.g. if the file doesn't contain any. -- tables like { [0]=0, [1]=len+1 }, e.g. if the file doesn't contain any.
local function bsearch(tab, searchelt) local function bsearch(tab, searchelt)
-- printf("bsearch(tab, %d)", searchelt) -- printf("bsearch(tab, %d)", searchelt)
local l, r = 1, #tab local l, r = 0, #tab
local i local i
if (r < 2) then if (r < 2) then
@ -642,7 +665,7 @@ local function bsearch(tab, searchelt)
return l return l
end end
local function getlinecol(pos) function getlinecol(pos) -- local
local line = bsearch(newlineidxs, pos) local line = bsearch(newlineidxs, pos)
assert(line and newlineidxs[line]<=pos and pos<newlineidxs[line+1]) assert(line and newlineidxs[line]<=pos and pos<newlineidxs[line+1])
local col = pos-newlineidxs[line] local col = pos-newlineidxs[line]
@ -679,14 +702,14 @@ local function TraceFunc(pat, label, doit)
return pat return pat
end end
local function BadIdentFunc(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
local line, col = getlinecol(pos) local line, col = getlinecol(pos)
printf("%d,%d: warning: bad identifier: %s", line, col, a) printf("%d,%d: warning: bad identifier: %s", line, col, a)
g_badids[a] = true g_badids[a] = true
end end
return true return true, a
end end
return lpeg.Cmt(Pat(pat), tfunc) return lpeg.Cmt(Pat(pat), tfunc)
end end
@ -696,7 +719,6 @@ end
local function Keyw(kwname) return TraceFunc(kwname, "kw", false) end local function Keyw(kwname) return TraceFunc(kwname, "kw", false) end
local function NotKeyw(text) return TraceFunc(text, "!kw", false) end local function NotKeyw(text) return TraceFunc(text, "!kw", false) end
local function Ident(idname) return TraceFunc(idname, "id", false) end local function Ident(idname) return TraceFunc(idname, "id", false) end
local function BadIdent(idname) return BadIdentFunc(idname) end
local function Stmt(cmdpat) return TraceFunc(cmdpat, "st", false) end local function Stmt(cmdpat) return TraceFunc(cmdpat, "st", false) end
--local function Temp(kwname) return TraceFunc(kwname, "temp", true) end --local function Temp(kwname) return TraceFunc(kwname, "temp", true) end
@ -706,7 +728,10 @@ local function Stmt(cmdpat) return TraceFunc(cmdpat, "st", false) end
-- attach the command names at the front! -- attach the command names at the front!
local 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 -- The always-nil-returning function at the end is so that every
-- command acts as a barrier to captures to prevent stack overflow (and
-- to make lpeg.match return a subject position at the end)
kwtab[cmdname] = (Keyw(cmdname) * cmdpat) / function() end
end end
end end
@ -782,6 +807,7 @@ attachnames(Cb)
local t_good_identifier = Range("AZ", "az", "__") * Range("AZ", "az", "__", "09")^0 local t_good_identifier = Range("AZ", "az", "__") * Range("AZ", "az", "__", "09")^0
t_good_identifier = lpeg.C(t_good_identifier)
-- CON isaltok also has chars in "{}.", but these could potentially -- CON isaltok also has chars in "{}.", but these could potentially
-- interfere with *CON* syntax. The "]" is so that the number in array[80] -- interfere with *CON* syntax. The "]" is so that the number in array[80]
@ -801,7 +827,9 @@ local Grammar = Pat{
-- omitted at the EOF. -- omitted at the EOF.
sp0 * ((con_outer_command + all_alt_pattern(Cb)) * sp1)^0, sp0 * ((con_outer_command + all_alt_pattern(Cb)) * sp1)^0,
-- Deps. These appear here because we're hitting a limit with LPeg else: -- Some often-used terminals follow. These appear here because we're
-- hitting a limit with LPeg else.
-- http://lua-users.org/lists/lua-l/2008-11/msg00462.html -- http://lua-users.org/lists/lua-l/2008-11/msg00462.html
-- NOTE: NW demo (NWSNOW.CON) contains a Ctrl-Z char (decimal 26) -- NOTE: NW demo (NWSNOW.CON) contains a Ctrl-Z char (decimal 26)
whitespace = Set(" \t\r\26") + newline + Set("(),;") + comment + linecomment, whitespace = Set(" \t\r\26") + newline + Set("(),;") + comment + linecomment,
@ -816,7 +844,7 @@ local Grammar = Pat{
-- getactor [THISACTOR].y y -- getactor [THISACTOR].y y
-- This is in need of cleanup! -- This is in need of cleanup!
t_identifier = -NotKeyw(con_keyword * (sp1 + "[")) * Ident(t_identifier_all), t_identifier = -NotKeyw(con_keyword * (sp1 + "[")) * Ident(t_identifier_all),
t_define = (Pat("-") * sp0)^-1 * (t_identifier + t_number), t_define = (t_maybe_minus * t_identifier + t_number),
t_arrayexp = t_identifier * arraypat * memberpat^-1, t_arrayexp = t_identifier * arraypat * memberpat^-1,