1
0
Fork 0
mirror of https://github.com/notwa/lips synced 2024-04-30 09:03:23 -07:00
lips/lips/Parser.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

95 lines
2.6 KiB
Lua

local insert = table.insert
local path = string.gsub(..., "[^.]+$", "")
local Base = require(path.."Base")
local Token = require(path.."Token")
local Lexer = require(path.."Lexer")
local Collector = require(path.."Collector")
local Preproc = require(path.."Preproc")
local Dumper = require(path.."Dumper")
local Parser = Base:extend()
function Parser:init(writer, fn, options)
self.writer = writer
self.fn = fn or '(string)'
self.main_fn = self.fn
self.options = options or {}
end
function Parser:tokenize(asm)
local lexer = Lexer(asm, self.main_fn, self.options)
local tokens = {}
local loop = true
while loop do
lexer:lex(function(tt, tok, fn, line)
assert(tt, 'Internal Error: missing token')
local t = Token(fn, line, tt, tok)
insert(tokens, t)
-- don't break if this is an included file's EOF
if tt == 'EOF' and fn == self.main_fn then
loop = false
end
end)
end
-- the lexer guarantees an EOL and EOF for a blank file
assert(#tokens > 0, 'Internal Error: no tokens after preprocessing')
local collector = Collector(self.options)
self.statements = collector:collect(tokens, self.main_fn)
end
function Parser:debug_dump()
local boring = {
tt = true,
tok = true,
fn = true,
line = true,
}
for i, s in ipairs(self.statements) do
local values = ''
for j, t in ipairs(s) do
local tok = t.tok
if type(tok) == 'number' then
tok = ("$%X"):format(tok)
end
values = values..'\t'..t.tt..'('..tostring(tok)..')'
for k, v in pairs(t) do
if not boring[k] then
values = values..'['..k..'='..tostring(v)..']'
end
end
end
values = values:sub(2)
print(s.line, s.type, values)
end
end
function Parser:parse(asm)
self:tokenize(asm)
if self.options.debug_token then self:debug_dump() end
local preproc = Preproc(self.options)
self.statements = preproc:process(self.statements)
if self.options.debug_pre then self:debug_dump() end
self.statements = preproc:expand(self.statements)
if self.options.debug_post then self:debug_dump() end
local dumper = Dumper(self.writer, self.options)
self.statements = dumper:load(self.statements)
if self.options.debug_asm then self:debug_dump() end
if self.options.labels then
dumper:export_labels(self.options.labels)
end
return dumper:dump()
end
return Parser