mirror of
https://github.com/notwa/lips
synced 2024-11-14 18:29:03 -08:00
more verbose errors
This commit is contained in:
parent
5f74f178d3
commit
1188543cd2
5 changed files with 37 additions and 66 deletions
|
@ -13,13 +13,6 @@ local Reader = require(path.."Reader")
|
||||||
|
|
||||||
local bitrange = util.bitrange
|
local bitrange = util.bitrange
|
||||||
|
|
||||||
local function label_delta(from, to)
|
|
||||||
-- TODO: consider removing the % here since .base should handle that now
|
|
||||||
to = to
|
|
||||||
from = from
|
|
||||||
return floor(to/4) - 1 - floor(from/4)
|
|
||||||
end
|
|
||||||
|
|
||||||
local Dumper = Reader:extend()
|
local Dumper = Reader:extend()
|
||||||
function Dumper:init(writer, options)
|
function Dumper:init(writer, options)
|
||||||
self.writer = writer
|
self.writer = writer
|
||||||
|
@ -42,13 +35,17 @@ function Dumper:export_labels(t)
|
||||||
return t
|
return t
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function Dumper:label_delta(from, to)
|
||||||
|
local rel = floor(to/4) - 1 - floor(from/4)
|
||||||
|
if rel > 0x8000 or rel <= -0x8000 then
|
||||||
|
self:error('branch too far', rel)
|
||||||
|
end
|
||||||
|
return rel % 0x10000
|
||||||
|
end
|
||||||
|
|
||||||
function Dumper:desym(t)
|
function Dumper:desym(t)
|
||||||
if t.tt == 'REL' then
|
if t.tt == 'REL' then
|
||||||
local rel = label_delta(self:pc(), t.tok)
|
return self:label_delta(self:pc(), t.tok)
|
||||||
if rel > 0x8000 or rel <= -0x8000 then
|
|
||||||
self:error('branch too far')
|
|
||||||
end
|
|
||||||
return rel % 0x10000
|
|
||||||
elseif type(t.tok) == 'number' then
|
elseif type(t.tok) == 'number' then
|
||||||
if t.offset then
|
if t.offset then
|
||||||
return t.tok + t.offset
|
return t.tok + t.offset
|
||||||
|
@ -69,11 +66,7 @@ function Dumper:desym(t)
|
||||||
return label
|
return label
|
||||||
end
|
end
|
||||||
|
|
||||||
local rel = label_delta(self:pc(), label)
|
return self:label_delta(self:pc(), label)
|
||||||
if rel > 0x8000 or rel <= -0x8000 then
|
|
||||||
self:error('branch too far')
|
|
||||||
end
|
|
||||||
return rel % 0x10000
|
|
||||||
end
|
end
|
||||||
error('Internal Error: failed to desym')
|
error('Internal Error: failed to desym')
|
||||||
end
|
end
|
||||||
|
@ -81,7 +74,7 @@ end
|
||||||
function Dumper:validate(n, bits)
|
function Dumper:validate(n, bits)
|
||||||
local max = 2^bits
|
local max = 2^bits
|
||||||
if n == nil then
|
if n == nil then
|
||||||
self:error('value is nil') -- internal error?
|
error('Internal Error: number to validate is nil', 2)
|
||||||
end
|
end
|
||||||
if n > max or n < 0 then
|
if n > max or n < 0 then
|
||||||
self:error('value out of range', ("%X"):format(n))
|
self:error('value out of range', ("%X"):format(n))
|
||||||
|
@ -110,34 +103,6 @@ function Dumper:write(t)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function Dumper:dump_instruction(t)
|
|
||||||
local uw = 0
|
|
||||||
local lw = 0
|
|
||||||
|
|
||||||
local o = t[1]
|
|
||||||
uw = uw + o*0x400
|
|
||||||
|
|
||||||
if #t == 2 then
|
|
||||||
local val = self:valvar(t[2], 26)
|
|
||||||
uw = uw + bitrange(val, 16, 25)
|
|
||||||
lw = lw + bitrange(val, 0, 15)
|
|
||||||
elseif #t == 4 then
|
|
||||||
uw = uw + self:valvar(t[2], 5)*0x20
|
|
||||||
uw = uw + self:valvar(t[3], 5)
|
|
||||||
lw = lw + self:valvar(t[4], 16)
|
|
||||||
elseif #t == 6 then
|
|
||||||
uw = uw + self:valvar(t[2], 5)*0x20
|
|
||||||
uw = uw + self:valvar(t[3], 5)
|
|
||||||
lw = lw + self:valvar(t[4], 5)*0x800
|
|
||||||
lw = lw + self:valvar(t[5], 5)*0x40
|
|
||||||
lw = lw + self:valvar(t[6], 6)
|
|
||||||
else
|
|
||||||
error('Internal Error: unknown n-size')
|
|
||||||
end
|
|
||||||
|
|
||||||
return uw, lw
|
|
||||||
end
|
|
||||||
|
|
||||||
function Dumper:assemble_j(first, out)
|
function Dumper:assemble_j(first, out)
|
||||||
local w = 0
|
local w = 0
|
||||||
w = w + self:valvar(first, 6) * 0x04000000
|
w = w + self:valvar(first, 6) * 0x04000000
|
||||||
|
@ -349,7 +314,7 @@ function Dumper:load(statements)
|
||||||
local align = s[1] and s[1].tok or 2
|
local align = s[1] and s[1].tok or 2
|
||||||
content = s[2] and s[2].tok or 0
|
content = s[2] and s[2].tok or 0
|
||||||
if align < 0 then
|
if align < 0 then
|
||||||
self:error('negative alignment')
|
self:error('negative alignment', align)
|
||||||
else
|
else
|
||||||
align = 2^align
|
align = 2^align
|
||||||
end
|
end
|
||||||
|
|
|
@ -249,7 +249,7 @@ function Lexer:lex_string(yield)
|
||||||
local bytes = {}
|
local bytes = {}
|
||||||
while true do
|
while true do
|
||||||
if self.chr == '\n' then
|
if self.chr == '\n' then
|
||||||
self:error('unimplemented')
|
self:error('unimplemented: newlines in strings')
|
||||||
yield('EOL', '\n')
|
yield('EOL', '\n')
|
||||||
self:nextc()
|
self:nextc()
|
||||||
elseif self.ord == self.EOF then
|
elseif self.ord == self.EOF then
|
||||||
|
|
|
@ -56,7 +56,7 @@ function Muncher:expect_EOL()
|
||||||
self:advance()
|
self:advance()
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
self:error('expected end of line')
|
self:error('expected end of line', self.tt)
|
||||||
end
|
end
|
||||||
|
|
||||||
function Muncher:optional_comma()
|
function Muncher:optional_comma()
|
||||||
|
@ -68,7 +68,7 @@ end
|
||||||
|
|
||||||
function Muncher:number()
|
function Muncher:number()
|
||||||
if self.tt ~= 'NUM' then
|
if self.tt ~= 'NUM' then
|
||||||
self:error('expected number')
|
self:error('expected number', self.tt)
|
||||||
end
|
end
|
||||||
local t = self.t
|
local t = self.t
|
||||||
self:advance()
|
self:advance()
|
||||||
|
@ -77,7 +77,7 @@ end
|
||||||
|
|
||||||
function Muncher:string()
|
function Muncher:string()
|
||||||
if self.tt ~= 'STRING' then
|
if self.tt ~= 'STRING' then
|
||||||
self:error('expected string')
|
self:error('expected string', self.tt)
|
||||||
end
|
end
|
||||||
local t = self.t
|
local t = self.t
|
||||||
self:advance()
|
self:advance()
|
||||||
|
@ -87,11 +87,11 @@ end
|
||||||
function Muncher:register(registers)
|
function Muncher:register(registers)
|
||||||
registers = registers or data.registers
|
registers = registers or data.registers
|
||||||
if self.tt ~= 'REG' then
|
if self.tt ~= 'REG' then
|
||||||
self:error('expected register')
|
self:error('expected register', self.tt)
|
||||||
end
|
end
|
||||||
local t = self.t
|
local t = self.t
|
||||||
if not registers[t.tok] then
|
if not registers[t.tok] then
|
||||||
self:error('wrong type of register')
|
self:error('wrong type of register', t.tok)
|
||||||
end
|
end
|
||||||
self:advance()
|
self:advance()
|
||||||
return self:token(t)
|
return self:token(t)
|
||||||
|
@ -99,16 +99,16 @@ end
|
||||||
|
|
||||||
function Muncher:deref()
|
function Muncher:deref()
|
||||||
if self.tt ~= 'OPEN' then
|
if self.tt ~= 'OPEN' then
|
||||||
self:error('expected opening parenthesis for dereferencing')
|
self:error('expected opening parenthesis for dereferencing', self.tt)
|
||||||
end
|
end
|
||||||
self:advance()
|
self:advance()
|
||||||
if self.tt ~= 'REG' then
|
if self.tt ~= 'REG' then
|
||||||
self:error('expected register to dereference')
|
self:error('expected register to dereference', self.tt)
|
||||||
end
|
end
|
||||||
local t = self.t
|
local t = self.t
|
||||||
self:advance()
|
self:advance()
|
||||||
if self.tt ~= 'CLOSE' then
|
if self.tt ~= 'CLOSE' then
|
||||||
self:error('expected closing parenthesis for dereferencing')
|
self:error('expected closing parenthesis for dereferencing', self.tt)
|
||||||
end
|
end
|
||||||
self:advance()
|
self:advance()
|
||||||
return self:token(t)
|
return self:token(t)
|
||||||
|
@ -119,7 +119,7 @@ function Muncher:const(relative, no_label)
|
||||||
self:error('expected constant', self.tt)
|
self:error('expected constant', self.tt)
|
||||||
end
|
end
|
||||||
if no_label and self.tt == 'LABELSYM' then
|
if no_label and self.tt == 'LABELSYM' then
|
||||||
self:error('labels are not allowed here')
|
self:error('labels are not allowed here', self.tt)
|
||||||
end
|
end
|
||||||
local t = self:token(self.t)
|
local t = self:token(self.t)
|
||||||
if relative then
|
if relative then
|
||||||
|
@ -135,19 +135,19 @@ end
|
||||||
|
|
||||||
function Muncher:special()
|
function Muncher:special()
|
||||||
if self.tt ~= 'SPECIAL' then
|
if self.tt ~= 'SPECIAL' then
|
||||||
self:error('expected special name to call')
|
self:error('expected special name to call', self.tt)
|
||||||
end
|
end
|
||||||
local name = self.tok
|
local name = self.tok
|
||||||
self:advance()
|
self:advance()
|
||||||
if self.tt ~= 'OPEN' then
|
if self.tt ~= 'OPEN' then
|
||||||
self:error('expected opening parenthesis for special call')
|
self:error('expected opening parenthesis for special call', self.tt)
|
||||||
end
|
end
|
||||||
|
|
||||||
local args = {}
|
local args = {}
|
||||||
while true do
|
while true do
|
||||||
local arg = self:advance()
|
local arg = self:advance()
|
||||||
if not arg_types[arg.tt] then
|
if not arg_types[arg.tt] then
|
||||||
self:error('invalid argument type')
|
self:error('invalid argument type', arg.tt)
|
||||||
else
|
else
|
||||||
self:advance()
|
self:advance()
|
||||||
end
|
end
|
||||||
|
@ -157,7 +157,7 @@ function Muncher:special()
|
||||||
insert(args, arg)
|
insert(args, arg)
|
||||||
break
|
break
|
||||||
else
|
else
|
||||||
self:error('unexpected token in argument list')
|
self:error('unexpected token in argument list', self.tt)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -90,7 +90,8 @@ function Preproc:check(s, i, tt)
|
||||||
i = i or self.i
|
i = i or self.i
|
||||||
local t = s[i]
|
local t = s[i]
|
||||||
if t == nil then
|
if t == nil then
|
||||||
self:error("expected another argument")
|
local err = ("expected another argument for %s at position %i"):format(self.s.type, self.i)
|
||||||
|
self:error(err)
|
||||||
end
|
end
|
||||||
|
|
||||||
self.fn = t.fn
|
self.fn = t.fn
|
||||||
|
|
|
@ -27,7 +27,8 @@ end
|
||||||
function Reader:expect(tts)
|
function Reader:expect(tts)
|
||||||
local t = self.s[self.i]
|
local t = self.s[self.i]
|
||||||
if t == nil then
|
if t == nil then
|
||||||
self:error("expected another argument") -- TODO: more verbose
|
local err = ("expected another argument for %s at position %i"):format(self.s.type, self.i)
|
||||||
|
self:error(err)
|
||||||
end
|
end
|
||||||
|
|
||||||
self.fn = t.fn
|
self.fn = t.fn
|
||||||
|
@ -39,8 +40,12 @@ function Reader:expect(tts)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--local err = ("argument %i of %s expected type %s"):format(self.i, self.s.type, tt)
|
local err
|
||||||
local err = ("unexpected type for argument %i of %s"):format(self.i, self.s.type)
|
if #tts == 1 then
|
||||||
|
err = ("argument %i of %s expected type %s"):format(self.i, self.s.type, tts[1])
|
||||||
|
else
|
||||||
|
err = ("unexpected type for argument %i of %s"):format(self.i, self.s.type)
|
||||||
|
end
|
||||||
self:error(err, t.tt)
|
self:error(err, t.tt)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -49,7 +54,7 @@ function Reader:register(registers)
|
||||||
local t = self.s[self.i]
|
local t = self.s[self.i]
|
||||||
local numeric = registers[t.tok]
|
local numeric = registers[t.tok]
|
||||||
if not numeric then
|
if not numeric then
|
||||||
self:error('wrong type of register')
|
self:error('wrong type of register', t.tok)
|
||||||
end
|
end
|
||||||
local new = Token(t)
|
local new = Token(t)
|
||||||
return new
|
return new
|
||||||
|
|
Loading…
Reference in a new issue