1
0
Fork 0
mirror of https://github.com/notwa/lips synced 2024-11-14 09:09:02 -08:00

properly compute offsets

This commit is contained in:
Connor Olding 2016-04-21 04:10:40 -07:00
parent 694f09c9e0
commit 6eac36584f
4 changed files with 57 additions and 44 deletions

View file

@ -160,8 +160,9 @@ function Collector:instruction()
elseif self.tt == 'UNARY' then
local peek = self.tokens[self.i + 1]
if peek.tt == 'VARSYM' then
local negate = t.tok == -1
t = self:advance()
t = Token(t):set('negate')
t = Token(t):set('negate', negate)
insert(s, t)
self:advance()
elseif peek.tt == 'EOL' or peek.tt == 'SEP' then

View file

@ -73,47 +73,6 @@ function Dumper:desym(t)
error('Internal Error: failed to desym')
end
function Dumper:toval(t)
if type(t) == 'number' then
return t
end
assert(type(t) == 'table', 'Internal Error: invalid value')
local val = self:desym(t)
if t.index then
val = val % 0x80000000
val = floor(val/4)
end
if t.negate then
val = -val
end
if t.portion == 'upper' then
val = bitrange(val, 16, 31)
elseif t.portion == 'lower' then
val = bitrange(val, 0, 15)
elseif t.portion == 'upperoff' then
local upper = bitrange(val, 16, 31)
local lower = bitrange(val, 0, 15)
if lower >= 0x8000 then
-- accommodate for offsets being signed
upper = (upper + 1) % 0x10000
end
val = upper
end
if t.negate or t.signed then
if val >= 0x10000 or val < -0x8000 then
self:error('value out of range', val)
end
val = val % 0x10000
end
return val
end
function Dumper:validate(n, bits)
local max = 2^bits
if n == nil then
@ -126,7 +85,16 @@ function Dumper:validate(n, bits)
end
function Dumper:valvar(t, bits)
local val = self:toval(t)
local val = t
local err
if type(val) ~= 'number' then
t.tok = self:desym(t)
t.tt = 'NUM'
val, err = t:compute()
if err then
self:error(err, val)
end
end
return self:validate(val, bits)
end

View file

@ -1,5 +1,10 @@
local floor = math.floor
local path = string.gsub(..., "[^.]+$", "")
local Base = require(path.."Base")
local util = require(path.."util")
local bitrange = util.bitrange
local Token = Base:extend()
function Token:init(...)
@ -63,4 +68,39 @@ function Token:set(key, value)
return self
end
function Token:compute()
assert(self.tt == 'NUM', 'Internal Error: cannot compute a non-number token')
local n = self.tok
if self.index then
n = n % 0x80000000
n = floor(n/4)
end
if self.negate then
n = -n
end
if self.portion == 'upper' then
n = bitrange(n, 16, 31)
elseif self.portion == 'lower' then
n = bitrange(n, 0, 15)
elseif self.portion == 'upperoff' then
local upper = bitrange(n, 16, 31)
local lower = bitrange(n, 0, 15)
if lower >= 0x8000 then
-- accommodate for offsets being signed
upper = (upper + 1) % 0x10000
end
n = upper
end
if self.negate or self.signed then
if n >= 0x10000 or n < -0x8000 then
return n, 'value out of range'
end
n = n % 0x10000
end
return n
end
return Token

View file

@ -16,7 +16,11 @@ local function tob_override(self, name)
else -- NUM or LABELSYM
local o = self:pop('CONST')
if self:peek('NUM') then
o:set('offset', self:pop('CONST').tok)
local temp, err = self:pop('CONST'):compute()
if err then
self:error(err, temp)
end
o:set('offset', temp)
end
offset = self:token(o)
if not o.portion then