1
0
Fork 0
mirror of https://github.com/notwa/mm synced 2024-11-05 04:49:03 -08:00
mm/Lua/lib/lips/Token.lua
2016-04-26 15:15:18 -07:00

111 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