1
0
Fork 0
mirror of https://github.com/notwa/lips synced 2024-04-30 00:53:23 -07:00

refactor label resolution into its own method

This commit is contained in:
Connor Olding 2016-11-27 16:17:32 -08:00
parent 29ae63ed34
commit 437b816f85

View File

@ -36,56 +36,55 @@ function Preproc:lookup(t)
if t.tok == nil then if t.tok == nil then
self:error('undefined variable', name) self:error('undefined variable', name)
end end
elseif self.do_labels and t.tt == 'RELLABELSYM' or t.tt == 'RELLABEL' then end
if t.tt == 'RELLABEL' then end
t.tt = 'LABEL'
-- exploits the fact that user labels can't begin with a number
local name = t.tok:sub(2)
t.tok = tostring(self.i)..name
elseif t.tt == 'RELLABELSYM' then
local i = self.i
t.tt = 'LABELSYM'
local rel = signs(t.tok) function Preproc:resolve(t)
assert(rel ~= 0, 'Internal Error: relative label without signs') if t.tt == 'RELLABEL' then
t.tt = 'LABEL'
-- exploits the fact that user labels can't begin with a number
local name = t.tok:sub(2)
t.tok = tostring(self.i)..name
elseif t.tt == 'RELLABELSYM' then
local i = self.i
t.tt = 'LABELSYM'
local name = t.tok:sub(abs(rel) + 1) local rel = signs(t.tok)
local seen = 0 assert(rel ~= 0, 'Internal Error: relative label without signs')
-- TODO: don't iterate over *every* label, just the ones nearby. local name = t.tok:sub(abs(rel) + 1)
-- we could do this by popping labels as we pass over them. local seen = 0
-- (would need to iterate once forwards and once backwards
-- for plus and minus labels respectively) -- TODO: don't iterate over *every* label, just the ones nearby.
if rel > 0 then -- we could do this by popping labels as we pass over them.
for _, rl in ipairs(self.plus_labels) do -- (would need to iterate once forwards and once backwards
if rl.name == name and rl.index > i then -- for plus and minus labels respectively)
seen = seen + 1 if rel > 0 then
if seen == rel then for _, rl in ipairs(self.plus_labels) do
t.tok = tostring(rl.index)..name if rl.name == name and rl.index > i then
break seen = seen + 1
end if seen == rel then
end t.tok = tostring(rl.index)..name
end break
else
for _, rl in ipairs(self.minus_labels) do
if rl.name == name and rl.index < i then
seen = seen - 1
if seen == rel then
t.tok = tostring(rl.index)..name
break
end
end end
end end
end end
else
if seen ~= rel then for _, rl in ipairs(self.minus_labels) do
self:error('could not find appropriate relative label', t.tok) if rl.name == name and rl.index < i then
seen = seen - 1
if seen == rel then
t.tok = tostring(rl.index)..name
break
end
end
end end
end end
else
return false if seen ~= rel then
self:error('could not find appropriate relative label', t.tok)
end
end end
return true
end end
function Preproc:check(s, i, tt) function Preproc:check(s, i, tt)
@ -115,7 +114,6 @@ function Preproc:process(statements)
self.variables = {} self.variables = {}
self.plus_labels = {} -- constructed forwards self.plus_labels = {} -- constructed forwards
self.minus_labels = {} -- constructed backwards self.minus_labels = {} -- constructed backwards
self.do_labels = false
-- first pass: resolve variables and collect relative labels -- first pass: resolve variables and collect relative labels
local new_statements = {} local new_statements = {}
@ -152,10 +150,9 @@ function Preproc:process(statements)
end end
-- second pass: resolve relative labels -- second pass: resolve relative labels
self.do_labels = true
for s in self:iter(new_statements) do for s in self:iter(new_statements) do
for j, t in ipairs(s) do for j, t in ipairs(s) do
self:lookup(t) self:resolve(t)
end end
end end