1
0
Fork 0
mirror of https://github.com/notwa/lips synced 2024-04-26 07:13:24 -07:00
lips/lips/Token.lua
Connor Olding f851540b24 various fixes, mostly for labels
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.
2016-04-24 03:55:12 -07:00

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