mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-12-25 03:00:46 +00:00
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:
parent
59df76f0b6
commit
5531888c8b
1 changed files with 43 additions and 15 deletions
|
@ -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,
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue