Improved error messages.

This commit is contained in:
g012 2017-09-27 23:57:50 +02:00
parent 55381d271b
commit 879b98eec4
3 changed files with 103 additions and 46 deletions

View File

@ -636,8 +636,9 @@ cycles_def=2 xcross_def=0 local opimm={
} M.opimm = opimm
for k,v in pairs(opimm) do
M[k .. 'imm'] = function(late, early)
local l65dbg = { info=debug.getinfo(2, 'Sl'), trace=debug.traceback(nil, 1) }
local size = function() late,early = size_op(late,early) return 2 end
local asbin = function(b) b[#b+1]=v.opc b[#b+1]=op_eval_byte(late,early) end
local asbin = function(b) local l65dbg=l65dbg b[#b+1]=v.opc b[#b+1]=op_eval_byte(late,early) end
table.insert(M.section_current.instructions, { size=size, cycles=2, asbin=asbin })
end
end
@ -650,8 +651,9 @@ cycles_def=3 xcross_def=0 local opzpg={
} M.opzpg = opzpg
for k,v in pairs(opzpg) do
M[k .. 'zpg'] = function(late, early)
local l65dbg = { info=debug.getinfo(2, 'Sl'), trace=debug.traceback(nil, 1) }
local size = function() late,early = size_op(late,early) return 2 end
local asbin = function(b) b[#b+1]=v.opc b[#b+1]=op_eval_byte(late,early) end
local asbin = function(b) local l65dbg=l65dbg b[#b+1]=v.opc b[#b+1]=op_eval_byte(late,early) end
table.insert(M.section_current.instructions, { size=size, cycles=v.cycles, asbin=asbin })
end
end
@ -664,8 +666,9 @@ cycles_def=4 xcross_def=0 local opabs={
} M.opabs = opabs
for k,v in pairs(opabs) do
M[k .. 'abs'] = function(late, early)
local l65dbg = { info=debug.getinfo(2, 'Sl'), trace=debug.traceback(nil, 1) }
local size = function() late,early = size_op(late,early) return 3 end
local asbin = function(b)
local asbin = function(b) local l65dbg=l65dbg
local x = op_eval_word(late,early)
b[#b+1]=v.opc b[#b+1]=x&0xff b[#b+1]=x>>8
end
@ -682,9 +685,10 @@ for k,_ in pairs(opzab) do
if x >= -32768 and x <= 0xffff then return M[k .. 'abs'](late, early) end
error("value out of word range: " .. x)
end
local l65dbg = { info=debug.getinfo(2, 'Sl'), trace=debug.traceback(nil, 1) }
local abs = opabs[k]
local ins = { cycles=abs.cycles }
ins.size = function()
ins.size = function() local l65dbg=l65dbg
local r,x = M.pcall_za(late, early or 0)
if not r then return 3 end
size_ref(x)
@ -700,7 +704,7 @@ for k,_ in pairs(opzab) do
ins.asbin = function(b) b[#b+1]=abs.opc b[#b+1]=x&0xff b[#b+1]=x>>8 end
return 3
end
ins.asbin = function(b)
ins.asbin = function(b) local l65dbg=l65dbg
local x = word_normalize(late(early or 0))
-- since we assumed absolute on link phase, we must generate absolute in binary
if x <= 0xff and opzpg[k] then print("warning: forcing abs on zpg operand for opcode " .. k) end
@ -716,8 +720,9 @@ cycles_def=4 xcross_def=0 local opzpx={
} M.opzpx = opzpx
for k,v in pairs(opzpx) do
M[k .. 'zpx'] = function(late, early)
local l65dbg = { info=debug.getinfo(2, 'Sl'), trace=debug.traceback(nil, 1) }
local size = function() late,early = size_op(late,early) return 2 end
local asbin = function(b) b[#b+1]=v.opc b[#b+1]=op_eval_byte(late,early) end
local asbin = function(b) local l65dbg=l65dbg b[#b+1]=v.opc b[#b+1]=op_eval_byte(late,early) end
table.insert(M.section_current.instructions, { size=size, cycles=v.cycles, asbin=asbin })
end
end
@ -729,8 +734,9 @@ cycles_def=4 xcross_def=1 local opabx={
} M.opabx = opabx
for k,v in pairs(opabx) do
M[k .. 'abx'] = function(late, early)
local l65dbg = { info=debug.getinfo(2, 'Sl'), trace=debug.traceback(nil, 1) }
local size = function() late,early = size_op(late,early) return 3 end
local asbin = function(b)
local asbin = function(b) local l65dbg=l65dbg
local x = op_eval_word(late,early)
b[#b+1]=v.opc b[#b+1]=x&0xff b[#b+1]=x>>8
end
@ -747,9 +753,10 @@ for k,_ in pairs(opzax) do
if x >= -32768 and x <= 0xffff then return M[k .. 'abx'](late, early) end
error("value out of word range: " .. x)
end
local l65dbg = { info=debug.getinfo(2, 'Sl'), trace=debug.traceback(nil, 1) }
local abx = opabx[k]
local ins = { cycles=abx.cycles }
ins.size = function()
ins.size = function() local l65dbg=l65dbg
local r,x = M.pcall_za(late, early or 0)
if not r then return 3 end
size_ref(x)
@ -765,7 +772,7 @@ for k,_ in pairs(opzax) do
ins.asbin = function(b) b[#b+1]=abx.opc b[#b+1]=x&0xff b[#b+1]=x>>8 end
return 3
end
ins.asbin = function(b)
ins.asbin = function(b) local l65dbg=l65dbg
local x = word_normalize(late(early or 0))
-- since we assumed absolute on link phase, we must generate absolute in binary
if x <= 0xff and opzpx[k] then print("warning: forcing abx on zpx operand for opcode " .. k) end
@ -780,8 +787,9 @@ cycles_def=4 xcross_def=0 local opzpy={
} M.opzpy = opzpy
for k,v in pairs(opzpy) do
M[k .. 'zpy'] = function(late, early)
local l65dbg = { info=debug.getinfo(2, 'Sl'), trace=debug.traceback(nil, 1) }
local size = function() late,early = size_op(late,early) return 2 end
local asbin = function(b) b[#b+1]=v.opc b[#b+1]=op_eval_byte(late,early) end
local asbin = function(b) local l65dbg=l65dbg b[#b+1]=v.opc b[#b+1]=op_eval_byte(late,early) end
table.insert(M.section_current.instructions, { size=size, cycles=v.cycles, asbin=asbin })
end
end
@ -793,8 +801,9 @@ cycles_def=4 xcross_def=1 local opaby={
} M.opaby = opaby
for k,v in pairs(opaby) do
M[k .. 'aby'] = function(late, early)
local l65dbg = { info=debug.getinfo(2, 'Sl'), trace=debug.traceback(nil, 1) }
local size = function() late,early = size_op(late,early) return 3 end
local asbin = function(b)
local asbin = function(b) local l65dbg=l65dbg
local x = op_eval_word(late,early)
b[#b+1]=v.opc b[#b+1]=x&0xff b[#b+1]=x>>8
end
@ -811,9 +820,10 @@ for k,_ in pairs(opzay) do
if x >= -32768 and x <= 0xffff then return M[k .. 'aby'](late, early) end
error("value out of word range: " .. x)
end
local l65dbg = { info=debug.getinfo(2, 'Sl'), trace=debug.traceback(nil, 1) }
local aby = opaby[k]
local ins = { cycles=aby.cycles }
ins.size = function()
ins.size = function() local l65dbg=l65dbg
local r,x = M.pcall_za(late, early or 0)
if not r then return 3 end
size_ref(x)
@ -829,7 +839,7 @@ for k,_ in pairs(opzay) do
ins.asbin = function(b) b[#b+1]=aby.opc b[#b+1]=x&0xff b[#b+1]=x>>8 end
return 3
end
ins.asbin = function(b)
ins.asbin = function(b) local l65dbg=l65dbg
local x = word_normalize(late(early or 0))
-- since we assumed absolute on link phase, we must generate absolute in binary
if x <= 0xff and opzpy[k] then print("warning: forcing aby on zpy operand for opcode " .. k) end
@ -843,6 +853,7 @@ cycles_def=2 xcross_def=0 local oprel={
} M.oprel = oprel
for k,v in pairs(oprel) do
M[k .. 'rel'] = function(label)
local l65dbg = { info=debug.getinfo(2, 'Sl'), trace=debug.traceback(nil, 1) }
local parent,offset = M.label_current
local section,rorg = M.section_current,M.location_current.rorg
local op = { cycles=2 }
@ -851,7 +862,7 @@ for k,v in pairs(oprel) do
label = size_dc(label)
return 2
end
op.asbin = function(b)
op.asbin = function(b) local l65dbg=l65dbg
local x,l = label,label
if type(x) == 'function' then x=x() end
if type(x) == 'string' then
@ -872,8 +883,9 @@ cycles_def=5 xcross_def=0 local opind={
} M.opind = opind
for k,v in pairs(opind) do
M[k .. 'ind'] = function(late, early)
local l65dbg = { info=debug.getinfo(2, 'Sl'), trace=debug.traceback(nil, 1) }
local size = function() late,early = size_op(late,early) return 3 end
local asbin = function(b)
local asbin = function(b) local l65dbg=l65dbg
local x = op_eval_word(late,early)
b[#b+1]=v.opc b[#b+1]=x&0xff b[#b+1]=x>>8
end
@ -887,8 +899,9 @@ cycles_def=6 xcross_def=0 local opinx={
} M.opinx = opinx
for k,v in pairs(opinx) do
M[k .. 'inx'] = function(late, early)
local l65dbg = { info=debug.getinfo(2, 'Sl'), trace=debug.traceback(nil, 1) }
local size = function() late,early = size_op(late,early) return 2 end
local asbin = function(b) b[#b+1]=v.opc b[#b+1]=op_eval_byte(late,early) end
local asbin = function(b) local l65dbg=l65dbg b[#b+1]=v.opc b[#b+1]=op_eval_byte(late,early) end
table.insert(M.section_current.instructions, { size=size, cycles=v.cycles, asbin=asbin })
end
end
@ -899,8 +912,9 @@ cycles_def=5 xcross_def=1 local opiny={
}
for k,v in pairs(opiny) do
M[k .. 'iny'] = function(late, early)
local l65dbg = { info=debug.getinfo(2, 'Sl'), trace=debug.traceback(nil, 1) }
local size = function() late,early = size_op(late,early) return 2 end
local asbin = function(b) b[#b+1]=v.opc b[#b+1]=op_eval_byte(late,early) end
local asbin = function(b) local l65dbg=l65dbg b[#b+1]=v.opc b[#b+1]=op_eval_byte(late,early) end
table.insert(M.section_current.instructions, { size=size, cycles=v.cycles, asbin=asbin })
end
end

View File

@ -77,7 +77,7 @@ static int writer(lua_State* L, const void* p, size_t size, void* f)
fprintf(f, "0x%02X, ", (int)(((unsigned char*)p)[i]));
}
w_o += size;
return size == 0;
return 0;
}
static int pmain(lua_State* L)

99
l65.lua
View File

@ -740,7 +740,7 @@ local function LexLua(src)
end
local function ParseLua(src)
local function ParseLua(src, src_name)
local st, tok
if type(src) ~= 'table' then
st, tok = LexLua(src)
@ -752,7 +752,7 @@ local function ParseLua(src)
end
--
local function GenerateError(msg)
local err = ">> :"..tok:Peek().Line..":"..tok:Peek().Char..": "..msg.."\n"
local err = (src_name or '=(string)') .. ":"..tok:Peek().Line..":"..tok:Peek().Char..": "..msg.."\n "
--find the line
local lineNum = 0
if type(src) == 'string' then
@ -760,7 +760,7 @@ local function ParseLua(src)
if line:sub(-1,-1) == '\n' then line = line:sub(1,-2) end
lineNum = lineNum+1
if lineNum == tok:Peek().Line then
err = err..">> '"..line:gsub('\t',' ').."'\n"
err = err..line:gsub('\t',' ').."\n"
for i = 1, tok:Peek().Char do
local c = line:sub(i,i)
if c == '\t' then
@ -769,7 +769,7 @@ local function ParseLua(src)
err = err..' '
end
end
err = err.." ^^^^"
err = err.."^^^^"
break
end
end
@ -2252,7 +2252,7 @@ local function Format65(ast)
appendNextToken( ")" )
else
print("Unknown AST Type: ", statement.AstType)
error(string.format("Unknown AST Type: %s\n", tostring(statement.AstType)))
end
assert(tok_it == #expr.Tokens + 1)
@ -2441,7 +2441,7 @@ local function Format65(ast)
elseif statement.AstType == 'SemicolonStatement' then
else
print("Unknown AST Type: ", statement.AstType)
error(string.format("Unknown AST Type: %s\n", tostring(statement.AstType)))
end
if statement.Semicolon then
@ -2478,6 +2478,52 @@ l65 = {
loadfile_org = loadfile,
dofile_org = dofile,
}
l65.report = function(success, ...)
if success then return success,... end
local message=... io.stderr:write(message..'\n')
os.exit(-1)
end
l65.msghandler = function(msg)
msg = tostring(msg)
msg = msg:gsub('%[string "(.-%.l65)"%]', '%1') -- [string "xxx.l65"] -> xxx.l65
local trace_cur = debug.traceback()
trace_cur = trace_cur:gsub('%[string "(.-%.l65)"%]', '%1') -- [string "xxx.l65"] -> xxx.l65
local i=2
while debug.getinfo(i) do
local j = 1
while true do
local n,v = debug.getlocal(i, j)
if not n then break end
if n == 'l65dbg' then
local o = function(s) io.stderr:write(s) end
o(string.format("%s\n", msg))
local trace_cur = debug.traceback()
if trace_cur:find("in local 'late'") then
local lines = {}
for line in trace_cur:gmatch("[^\n]+") do
if line:find("in local 'late'") then break end
table.insert(lines, line)
end
print(table.concat(lines,'\n'))
end
local trace = v.trace:match(".-\n(.*)\n.-'xpcall'")
trace = trace:gsub('%[string "(.-%.l65)"%]', '%1')
print(trace)
os.exit(-2)
end
j = j + 1
end
i = i + 1
end
trace_cur = trace_cur:match(".-\n(.*)\n.-'xpcall'")
io.stderr:write(string.format("%s\n%s\n", msg, trace_cur))
os.exit(-3)
end
l65.require = function()
-- TODO
end
do
local getembedded = type(arg[-1]) == 'function' and arg[-1]
l65.load_embedded = function(name)
@ -2485,15 +2531,14 @@ do
local src,isl65 = getembedded(name)
if not src then return end
if isl65 then
local filename = name .. '.l65'
local st, ast = assert(l65.parse(src))
local bc = assert(l65.load_org(l65.format(ast), filename))
return bc, filename
name = name .. '.l65'
local st, ast = l65.report(l65.parse(src, name))
src = l65.format(ast)
else
local filename = name .. '.lua'
local bc = assert(l65.load_org(src, filename))
return bc, filename
name = name .. '.lua'
end
local bc = assert(l65.load_org(src, name))
return bc, name
end
end
l65.searcher = function(name)
@ -2502,7 +2547,7 @@ l65.searcher = function(name)
local file = assert(io.open(filename, 'rb'))
local src = file:read('*a')
file:close()
local st, ast = assert(l65.parse(src))
local st, ast = l65.report(l65.parse(src, filename))
local bc = assert(l65.load_org(l65.format(ast), filename))
return bc, filename
end
@ -2514,14 +2559,10 @@ l65.load = function(chunk, chunkname, mode, ...)
s = table.concat(s)
else return nil, string.format("invalid type for chunk %s: %s", chunkname or "=(load)", chunk_t)
end
local st, ast = l65.parse(s)
if not st then
if not mode or mode:sub(1,1)=='b' then
local f = l65.load_org(s, chunkname, mode, ...)
if f then return f end
end
return nil,ast
if s:sub(1,4) == "\x1bLua" then -- a binary file
return l65.load_org(s, chunkname, mode, ...)
end
local st, ast = l65.report(l65.parse(s, chunkname or "=(load)"))
return l65.load_org(l65.format(ast), chunkname, 't', ...)
end
l65.loadfile = function(filename, mode, ...)
@ -2536,8 +2577,8 @@ l65.loadfile = function(filename, mode, ...)
return l65.load(s, filename, mode, ...)
end
l65.dofile = function(filename)
local f = assert(l65.loadfile(filename))
return f()
local f = l65.report(l65.loadfile(filename))
return xpcall(f, l65.msghandler)
end
l65.installhooks = function()
if package.searchers[l65.searcher_index] ~= l65.searcher then
@ -2599,17 +2640,19 @@ local cfg=require"l65cfg" l65.cfg=cfg
local version = function()
print(string.format("l65 %s", cfg.version))
end
local usage = function()
print(string.format([[
local usage = function(f)
if not f then f = io.stdout end
f:write(string.format([[
Usage: %s [options] file
Options:
-d <file> Dump the Lua code after l65 parsing into file
-h Display this information
-v Display the release version]], arg[0]))
-v Display the release version
]], arg[0]))
end
local invalid_usage = function()
print("Invalid usage.")
usage()
io.stderr:write("Invalid usage.\n")
usage(io.stderr)
end
local inf,dump