mirror of
https://github.com/notwa/lips
synced 2024-05-09 12:33:22 -07:00
Connor Olding
f851540b24
reimplement modulo by 0x80000000 for labels. allow numeric label values ("REL") to be "fixed" to bypass label calculation. add offsets after label calculation instead of before. properly check for EOL after all expected arguments have been exhausted. finally, add token properties to debug dumps.
112 lines
2.6 KiB
Lua
112 lines
2.6 KiB
Lua
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(...)
|
|
local args = {...}
|
|
if #args == 1 then
|
|
local t = args[1]
|
|
if type(t) == 'table' then
|
|
for k, v in pairs(t) do
|
|
self[k] = v
|
|
end
|
|
end
|
|
elseif #args == 3 then
|
|
self.fn = args[1]
|
|
self.line = args[2]
|
|
local t = args[3]
|
|
if type(t) == 'table' then
|
|
self.tt = t[1]
|
|
self.tok = t[2]
|
|
elseif type(t) == 'string' then
|
|
self.tt = 'REG'
|
|
self.tok = t
|
|
elseif type(t) == 'number' then
|
|
self.tt = 'NUM'
|
|
self.tok = t
|
|
else
|
|
error('Internal Error: unknown type to construct', 3)
|
|
end
|
|
elseif #args == 4 then
|
|
self.fn = args[1]
|
|
self.line = args[2]
|
|
self.tt = args[3]
|
|
self.tok = args[4]
|
|
else
|
|
error('Internal Error: init takes 1, 3 or 4 arguments', 3)
|
|
end
|
|
self:validate(1)
|
|
return self
|
|
end
|
|
|
|
function Token:validate(n)
|
|
n = (n or 0) + 3 -- depth for error message
|
|
if not self.fn then
|
|
error('Internal Error: tokens require a filename', n)
|
|
end
|
|
if not self.line then
|
|
error('Internal Error: tokens require a line number', n)
|
|
end
|
|
if not self.tt then
|
|
error('Internal Error: token is missing a type', n)
|
|
end
|
|
if not self.tok then
|
|
error('Internal Error: token is missing a value', n)
|
|
end
|
|
end
|
|
|
|
function Token:set(key, value)
|
|
if value == nil then
|
|
value = true
|
|
end
|
|
self[key] = value
|
|
return self
|
|
end
|
|
|
|
function Token:compute(n)
|
|
local n = n or self.tok
|
|
assert(n or self.tt == 'NUM', 'Internal Error: cannot compute a non-number token')
|
|
|
|
if self.offset then
|
|
n = n + self.offset
|
|
end
|
|
|
|
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.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
|