1
0
Fork 0
mirror of https://github.com/notwa/mm synced 2024-06-01 10:53:05 -07:00
mm/Lua/lib/lips/Reader.lua
2016-04-26 15:15:18 -07:00

99 lines
2.3 KiB
Lua

local path = string.gsub(..., "[^.]+$", "")
local Base = require(path.."Base")
local Token = require(path.."Token")
local Reader = Base:extend()
-- no base init method
-- Reader expects self.s to be set to a statement, and self.i to a token index
function Reader:error(msg, got)
if got ~= nil then
msg = msg..', got '..tostring(got)
end
error(('%s:%d: Error: %s'):format(self.fn, self.line, msg), 2)
end
function Reader:token(t, ...)
local new
if type(t) == 'table' then
new = Token(t, ...)
else
new = Token(self.fn, self.line, t, ...)
end
return new
end
function Reader:expect(tts)
local t = self.s[self.i]
if t == nil then
local err = ("expected another argument for %s at position %i"):format(self.s.type, self.i)
self:error(err)
end
self.fn = t.fn
self.line = t.line
for _, tt in pairs(tts) do
if t.tt == tt then
return t.ok
end
end
local err
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)
end
function Reader:register(registers)
self:expect{'REG'}
local t = self.s[self.i]
local numeric = registers[t.tok]
if not numeric then
self:error('wrong type of register', t.tok)
end
local new = Token(t)
return new
end
function Reader:const(relative, no_label)
self:expect{'NUM', 'LABELSYM', 'LABELREL'}
local t = self.s[self.i]
-- overrides will want to LUI a label; let portioned labels pass
if no_label and not t.portion then
self:expect{'NUM', 'LABELREL'}
end
local new = Token(t)
if relative then -- you probably shouldn't use this in Preproc
if t.tt == 'LABELSYM' then
new.tt = 'LABELREL'
elseif t.tt == 'NUM' then
new.tt = 'REL'
end
end
return new
end
function Reader:deref()
self:expect{'DEREF'}
local t = self.s[self.i]
local new = Token(t)
--new.tt = 'REG'
return new
end
function Reader:peek(tt)
local t = self.s[self.i]
local seen = t and t.tt or nil
if tt ~= nil then
return seen == tt
end
return t
end
return Reader