mirror of
https://github.com/g012/l65.git
synced 2025-01-30 14:34:25 +00:00
Improved error messages.
This commit is contained in:
parent
55381d271b
commit
879b98eec4
48
6502.lua
48
6502.lua
@ -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
|
||||
|
2
embed.c
2
embed.c
@ -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
99
l65.lua
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user