1
0
Fork 0
mirror of https://github.com/notwa/lips synced 2024-05-03 01:53:23 -07:00
lips/lips/Reader.lua

99 lines
2.3 KiB
Lua
Raw Permalink Normal View History

2016-04-21 00:07:07 -07:00
local path = string.gsub(..., "[^.]+$", "")
local Base = require(path.."Base")
local Token = require(path.."Token")
local Reader = Base:extend()
2016-04-21 03:23:04 -07:00
-- no base init method
2016-04-21 00:07:07 -07:00
-- 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
2016-04-23 16:24:46 -07:00
local err = ("expected another argument for %s at position %i"):format(self.s.type, self.i)
self:error(err)
2016-04-21 00:07:07 -07:00
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
2016-04-23 16:24:46 -07:00
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
2016-04-21 00:07:07 -07:00
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
2016-04-23 16:24:46 -07:00
self:error('wrong type of register', t.tok)
2016-04-21 00:07:07 -07:00
end
local new = Token(t)
return new
end
function Reader:const(relative, no_label)
self:expect{'NUM', 'LABELSYM', 'LABELREL'}
2016-04-21 00:07:07 -07:00
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
2016-04-21 00:07:07 -07:00
local new = Token(t)
if relative then -- you probably shouldn't use this in Preproc
2016-04-21 00:07:07 -07:00
if t.tt == 'LABELSYM' then
new.tt = 'LABELREL'
elseif t.tt == 'NUM' then
new.tt = 'REL'
2016-04-21 00:07:07 -07:00
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