mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-11-11 07:11:39 +00:00
Lunatic translator: in error tracebacks, show line numbers of the source file.
Instead of those of the translated code. Also some codegen tweaks and fixes. git-svn-id: https://svn.eduke32.com/eduke32@3535 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
parent
ba0970cede
commit
bad2da3026
4 changed files with 153 additions and 24 deletions
|
@ -1482,10 +1482,26 @@ do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
concode = lunacon.compile(confn)
|
local lineinfo
|
||||||
|
concode, lineinfo = lunacon.compile(confn)
|
||||||
|
assert(lineinfo)
|
||||||
|
|
||||||
if (concode == nil) then
|
if (concode == nil) then
|
||||||
error("Failure compiling CON code, exiting.", 0)
|
error("Failure compiling CON code, exiting.", 0)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Translate one Lua line number to a CON file name + line number
|
||||||
|
local function transline(lnum)
|
||||||
|
return string.format("%s:%d", lineinfo:getfline(tonumber(lnum)))
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Register the function that tweaks an error message, looking out for
|
||||||
|
-- errors from CON and translating the line numbers.
|
||||||
|
local function tweak_traceback_msg(errmsg)
|
||||||
|
return errmsg:gsub('%[string "CON"%]:([0-9]+)', transline)
|
||||||
|
end
|
||||||
|
|
||||||
|
set_tweak_traceback_internal(tweak_traceback_msg)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- change the environment of this chunk to the table G_
|
-- change the environment of this chunk to the table G_
|
||||||
|
|
|
@ -425,14 +425,18 @@ local walltype_mt = {
|
||||||
end,
|
end,
|
||||||
|
|
||||||
_set_nextwall = function(w, nextwall)
|
_set_nextwall = function(w, nextwall)
|
||||||
-- XXX: this disallows making a red wall white
|
-- NOTE: Allow setting a wall to white too, but no checking of the
|
||||||
bcheck.wall_idx(nextwall)
|
-- consistency invariant ".nextwall>=0 iff .nextsector>=0".
|
||||||
|
if (not (nextwall < 0)) then
|
||||||
|
bcheck.wall_idx(nextwall)
|
||||||
|
end
|
||||||
ffi.cast(walltype_ptr_ct, w).nextwall = nextwall
|
ffi.cast(walltype_ptr_ct, w).nextwall = nextwall
|
||||||
end,
|
end,
|
||||||
|
|
||||||
_set_nextsector = function(w, nextsector)
|
_set_nextsector = function(w, nextsector)
|
||||||
-- XXX: this disallows making a red wall white
|
if (not (nextsector < 0)) then
|
||||||
check_sector_idx(nextsector)
|
check_sector_idx(nextsector)
|
||||||
|
end
|
||||||
ffi.cast(walltype_ptr_ct, w).nextsector = nextsector
|
ffi.cast(walltype_ptr_ct, w).nextsector = nextsector
|
||||||
end,
|
end,
|
||||||
|
|
||||||
|
@ -679,7 +683,7 @@ function GenStructMetatable(Structname, Boundname, StaticMembersTab)
|
||||||
if (key >= 0 and key < ffiC[Boundname]) then
|
if (key >= 0 and key < ffiC[Boundname]) then
|
||||||
return ffiC[Structname][key]
|
return ffiC[Structname][key]
|
||||||
end
|
end
|
||||||
error("out-of-bounds "..Structname.."[] read access", 2)
|
error("out-of-bounds "..Structname.."[] read access with index "..key, 2)
|
||||||
elseif (type(key)=="string") then
|
elseif (type(key)=="string") then
|
||||||
return StaticMembersTab[key]
|
return StaticMembersTab[key]
|
||||||
end
|
end
|
||||||
|
|
|
@ -18,6 +18,7 @@ local loadstring = loadstring
|
||||||
local pairs = pairs
|
local pairs = pairs
|
||||||
local pcall = pcall
|
local pcall = pcall
|
||||||
local print = print
|
local print = print
|
||||||
|
local setmetatable = setmetatable
|
||||||
local tonumber = tonumber
|
local tonumber = tonumber
|
||||||
local tostring = tostring
|
local tostring = tostring
|
||||||
local type = type
|
local type = type
|
||||||
|
@ -98,7 +99,7 @@ local g_warn = { ["not-redefined"]=true, ["bad-identifier"]=true,
|
||||||
["number-conversion"]=true, ["system-gamevar"]=true, }
|
["number-conversion"]=true, ["system-gamevar"]=true, }
|
||||||
|
|
||||||
-- Code generation options.
|
-- Code generation options.
|
||||||
local g_cgopt = { ["no"]=false, }
|
local g_cgopt = { ["no"]=false, ["debug-lineinfo"]=false, }
|
||||||
|
|
||||||
-- How many 'if' statements are following immediately each other,
|
-- How many 'if' statements are following immediately each other,
|
||||||
-- needed to cope with CONs dangling-else resolution
|
-- needed to cope with CONs dangling-else resolution
|
||||||
|
@ -2038,9 +2039,9 @@ local Cinner = {
|
||||||
displayrandvarvar = cmd(W,R)
|
displayrandvarvar = cmd(W,R)
|
||||||
/ "%1=_con._displayrand(%2)",
|
/ "%1=_con._displayrand(%2)",
|
||||||
dist = cmd(W,R,R)
|
dist = cmd(W,R,R)
|
||||||
/ "%1=_xmath.dist(sprite[%1],sprite[%2])",
|
/ "%1=_xmath.dist(sprite[%2],sprite[%3])",
|
||||||
ldist = cmd(W,R,R)
|
ldist = cmd(W,R,R)
|
||||||
/ "%1=_xmath.ldist(sprite[%1],sprite[%2])",
|
/ "%1=_xmath.ldist(sprite[%2],sprite[%3])",
|
||||||
dragpoint = cmd(R,R,R)
|
dragpoint = cmd(R,R,R)
|
||||||
/ handle.NYI,
|
/ handle.NYI,
|
||||||
rotatepoint = cmd(R,R,R,R,R,W,W)
|
rotatepoint = cmd(R,R,R,R,R,W,W)
|
||||||
|
@ -2420,7 +2421,7 @@ 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, "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 Stmt(cmdpat) return TraceFunc(cmdpat, "st", false) end
|
local function Stmt(cmdpat) return TraceFunc(cmdpat, "st", false) end
|
||||||
|
|
||||||
|
@ -2428,33 +2429,37 @@ local function Stmt(cmdpat) return TraceFunc(cmdpat, "st", false) end
|
||||||
--Cinner["myosx"] = Temp(Cinner["myosx"])
|
--Cinner["myosx"] = Temp(Cinner["myosx"])
|
||||||
|
|
||||||
----==== Translator continued ====----
|
----==== Translator continued ====----
|
||||||
local function after_inner_cmd_Cmt(subj, pos, ...)
|
local function attachlinenum(capts, pos)
|
||||||
local capts = {...}
|
capts[1] = capts[1].."--"..getlinecol(pos)
|
||||||
|
return capts[1]
|
||||||
|
end
|
||||||
|
|
||||||
|
local function after_inner_cmd_Cmt(subj, pos, ...)
|
||||||
if (g_numerrors == inf) then
|
if (g_numerrors == inf) then
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local capts = {...}
|
||||||
if (type(capts[1])=="string" and capts[2]==nil) then
|
if (type(capts[1])=="string" and capts[2]==nil) then
|
||||||
return true, capts[1] .."--"..linecolstr(pos) --TEMP
|
return true, attachlinenum(capts, pos)
|
||||||
end
|
end
|
||||||
|
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
local function after_if_cmd_Cmt(subj, pos, ...)
|
local function after_if_cmd_Cmt(subj, pos, ...)
|
||||||
local capts = {...}
|
|
||||||
|
|
||||||
if (g_numerrors == inf) then
|
if (g_numerrors == inf) then
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local capts = {...}
|
||||||
if (capts[1] ~= nil) then
|
if (capts[1] ~= nil) then
|
||||||
assert(#capts <= 3)
|
assert(#capts <= 3)
|
||||||
for i=1,#capts do
|
for i=1,#capts do
|
||||||
assert(type(capts[i]=="string"))
|
assert(type(capts[i]=="string"))
|
||||||
end
|
end
|
||||||
return true, unpack(capts, 1, #capts)
|
-- attachlinenum(capts, pos)
|
||||||
|
return true, unpack(capts)
|
||||||
end
|
end
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
@ -2745,7 +2750,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 = -NotKeyw(conl.keyword * (sp1 + "[")) * tok.identifier_all,
|
t_identifier = -(conl.keyword * (sp1 + "[")) * tok.identifier_all,
|
||||||
-- TODO?: SST TC has e.g. "1267AT", relying on it to be parsed as a number "1267".
|
-- TODO?: SST TC has e.g. "1267AT", relying on it to be parsed as a number "1267".
|
||||||
-- However, this conflicts with bad-identifiers, so it should be checked last.
|
-- However, this conflicts with bad-identifiers, so it should be checked last.
|
||||||
-- This would also handle LNGA2's "00000000h", though would give problems with
|
-- This would also handle LNGA2's "00000000h", though would give problems with
|
||||||
|
@ -2853,8 +2858,77 @@ local function flatten_codetab(codetab)
|
||||||
return tmpcode
|
return tmpcode
|
||||||
end
|
end
|
||||||
|
|
||||||
local function get_code_string(codetab)
|
|
||||||
return table.concat(flatten_codetab(g_curcode), "\n")
|
--== Lua -> CON line number mapping for error messages ==--
|
||||||
|
|
||||||
|
local lineinfo_mt = {
|
||||||
|
__index = {
|
||||||
|
-- Get CON file name and CON line number from Lua line number.
|
||||||
|
getfline = function(self, lualine)
|
||||||
|
local llines, lfiles = self.llines, self.lfiles
|
||||||
|
assert(lualine >= 1 and lualine <= #llines)
|
||||||
|
|
||||||
|
-- Get the CON line number: a simple lookup.
|
||||||
|
local conline = llines[lualine]
|
||||||
|
|
||||||
|
-- Find the CON file name next.
|
||||||
|
local confile = nil
|
||||||
|
for i=1,#lfiles do
|
||||||
|
if (lfiles[i].line > lualine) then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
-- Shorten the file name by stripping the directory parts.
|
||||||
|
confile = lfiles[i].name:match("[^/]+$")
|
||||||
|
end
|
||||||
|
|
||||||
|
return confile or "???", conline
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
|
||||||
|
__metatable = true,
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Construct Lua->CON line mapping info. This walks the generated code and
|
||||||
|
-- looks for our inserted comment strings, so it's kind of hackish.
|
||||||
|
local function get_lineinfo(flatcode)
|
||||||
|
local curline, curfile = { 0 }, { "<none>" } -- stacks
|
||||||
|
-- llines: [<Lua code line number>] = <CON code line number>
|
||||||
|
-- lfiles: [<sequence number>] = { line=<Lua line number>, name=<filename> }
|
||||||
|
local llines, lfiles = {}, {}
|
||||||
|
|
||||||
|
for i=1,#flatcode do
|
||||||
|
local code = flatcode[i]
|
||||||
|
|
||||||
|
local lnumstr = code:match("%-%-([0-9]+)$")
|
||||||
|
local begfn = lnumstr and nil or code:match("^%-%- BEGIN (.+)$")
|
||||||
|
local endfn = lnumstr and nil or code:match("^%-%- END (.+)$")
|
||||||
|
|
||||||
|
if (lnumstr) then
|
||||||
|
curline[#curline] = assert(tonumber(lnumstr))
|
||||||
|
elseif (begfn) then
|
||||||
|
curfile[#curfile+1] = begfn
|
||||||
|
curline[#curline+1] = 1
|
||||||
|
-- Begin an included file.
|
||||||
|
lfiles[#lfiles+1] = { line=i, name=begfn }
|
||||||
|
elseif (endfn) then
|
||||||
|
assert(endfn==curfile[#curfile]) -- assert proper nesting
|
||||||
|
curfile[#curfile] = nil
|
||||||
|
curline[#curline] = nil
|
||||||
|
-- End an included file, so reset the name to the includer's one.
|
||||||
|
lfiles[#lfiles+1] = { line=i, name=curfile[#curfile] }
|
||||||
|
end
|
||||||
|
|
||||||
|
llines[i] = assert(curline[#curline])
|
||||||
|
end
|
||||||
|
|
||||||
|
return setmetatable({ llines=llines, lfiles=lfiles }, lineinfo_mt)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- <lineinfop>: Get line info?
|
||||||
|
local function get_code_string(codetab, lineinfop)
|
||||||
|
local flatcode = flatten_codetab(codetab)
|
||||||
|
local lineinfo = lineinfop and get_lineinfo(flatcode)
|
||||||
|
return table.concat(flatcode, "\n"), lineinfo
|
||||||
end
|
end
|
||||||
|
|
||||||
function on.parse_begin()
|
function on.parse_begin()
|
||||||
|
@ -2957,6 +3031,9 @@ local function handle_cmdline_arg(str)
|
||||||
g_cgopt["no"] = true
|
g_cgopt["no"] = true
|
||||||
ok = true
|
ok = true
|
||||||
end
|
end
|
||||||
|
elseif (str:sub(2)=="fdebug-lineinfo") then
|
||||||
|
g_cgopt["debug-lineinfo"] = true
|
||||||
|
ok = true
|
||||||
elseif (kind=="I" and #str >= 3) then
|
elseif (kind=="I" and #str >= 3) then
|
||||||
-- default directory (only ONCE, not search path)
|
-- default directory (only ONCE, not search path)
|
||||||
g_defaultDir = str:sub(3)
|
g_defaultDir = str:sub(3)
|
||||||
|
@ -3020,15 +3097,19 @@ if (string.dump) then
|
||||||
local io = require("io")
|
local io = require("io")
|
||||||
local file = onlycheck and io.stdout or io.stderr
|
local file = onlycheck and io.stdout or io.stderr
|
||||||
|
|
||||||
local code = get_code_string(g_curcode)
|
local code, lineinfo = get_code_string(g_curcode, g_cgopt["debug-lineinfo"])
|
||||||
local func, errmsg = loadstring(code, "CON")
|
local func, errmsg = loadstring(code, "CON")
|
||||||
|
|
||||||
file:write(format("-- GENERATED CODE for \"%s\":\n", filename))
|
-- file:write(format("-- GENERATED CODE for \"%s\":\n", filename))
|
||||||
if (func == nil) then
|
if (func == nil) then
|
||||||
file:write(format("-- (invalid Lua code: %s)\n", errmsg))
|
file:write(format("-- INVALID Lua CODE: %s\n", errmsg))
|
||||||
end
|
end
|
||||||
|
|
||||||
if (not onlycheck) then
|
if (lineinfo) then
|
||||||
|
for i=1,#lineinfo.llines do
|
||||||
|
file:write(format("%d -> %s:%d\n", i, lineinfo:getfline(i)))
|
||||||
|
end
|
||||||
|
elseif (not onlycheck) then
|
||||||
file:write(code)
|
file:write(code)
|
||||||
file:write("\n")
|
file:write("\n")
|
||||||
end
|
end
|
||||||
|
@ -3052,6 +3133,6 @@ else
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return get_code_string(g_curcode)
|
return get_code_string(g_curcode, true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -30,6 +30,9 @@ int32_t g_elEventRETURN;
|
||||||
uint32_t g_eventCalls[MAXEVENTS], g_actorCalls[MAXTILES];
|
uint32_t g_eventCalls[MAXEVENTS], g_actorCalls[MAXTILES];
|
||||||
double g_eventTotalMs[MAXEVENTS], g_actorTotalMs[MAXTILES];
|
double g_eventTotalMs[MAXEVENTS], g_actorTotalMs[MAXTILES];
|
||||||
|
|
||||||
|
// Used as Lua registry key to the tweak_traceback_msg() function, set to 1 if
|
||||||
|
// such a function has been registered.
|
||||||
|
static uint8_t g_tweakTracebackMsg = 0;
|
||||||
|
|
||||||
// forward-decls...
|
// forward-decls...
|
||||||
static int32_t SetEvent_CF(lua_State *L);
|
static int32_t SetEvent_CF(lua_State *L);
|
||||||
|
@ -219,9 +222,32 @@ static int our_traceback_CF(lua_State *L)
|
||||||
lua_call(L, 1, 1);
|
lua_call(L, 1, 1);
|
||||||
Bassert(lua_gettop(L)==2); // Lua will pop off args
|
Bassert(lua_gettop(L)==2); // Lua will pop off args
|
||||||
|
|
||||||
|
if (g_tweakTracebackMsg)
|
||||||
|
{
|
||||||
|
// Get tweak_traceback_msg() onto the stack.
|
||||||
|
lua_pushlightuserdata(L, &g_tweakTracebackMsg);
|
||||||
|
lua_gettable(L, LUA_REGISTRYINDEX);
|
||||||
|
|
||||||
|
lua_pushvalue(L, -2); // push copy of error message string
|
||||||
|
Bassert(lua_type(L, -1)==LUA_TSTRING);
|
||||||
|
|
||||||
|
// Call tweak_traceback_msg(). CAREFUL, it's unprotected!
|
||||||
|
lua_call(L, 1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Registers a function: str = tweak_traceback_msg(str)
|
||||||
|
static int32_t SetTweakTracebackMsg_CF(lua_State *L)
|
||||||
|
{
|
||||||
|
Bassert(lua_gettop(L)==1);
|
||||||
|
L_CheckAndRegisterFunction(L, &g_tweakTracebackMsg);
|
||||||
|
g_tweakTracebackMsg = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
////// Lua C-API interfaces for C game functions that may call events.
|
////// Lua C-API interfaces for C game functions that may call events.
|
||||||
// http://www.freelists.org/post/luajit/intermitten-lua-pcall-crash-on-x86-64-linux,1
|
// http://www.freelists.org/post/luajit/intermitten-lua-pcall-crash-on-x86-64-linux,1
|
||||||
|
|
||||||
|
@ -332,6 +358,8 @@ static void El_StateSetup(lua_State *L)
|
||||||
lua_setglobal(L, "gameevent_internal");
|
lua_setglobal(L, "gameevent_internal");
|
||||||
lua_pushcfunction(L, SetActor_CF);
|
lua_pushcfunction(L, SetActor_CF);
|
||||||
lua_setglobal(L, "gameactor_internal");
|
lua_setglobal(L, "gameactor_internal");
|
||||||
|
lua_pushcfunction(L, SetTweakTracebackMsg_CF);
|
||||||
|
lua_setglobal(L, "set_tweak_traceback_internal");
|
||||||
|
|
||||||
El_PushCFunctions(L);
|
El_PushCFunctions(L);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue