mirror of
https://github.com/notwa/lips
synced 2024-11-14 14:59:03 -08:00
refactor label resolution into its own method
This commit is contained in:
parent
29ae63ed34
commit
437b816f85
1 changed files with 41 additions and 44 deletions
|
@ -36,56 +36,55 @@ function Preproc:lookup(t)
|
|||
if t.tok == nil then
|
||||
self:error('undefined variable', name)
|
||||
end
|
||||
elseif self.do_labels and t.tt == 'RELLABELSYM' or t.tt == 'RELLABEL' then
|
||||
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'
|
||||
end
|
||||
end
|
||||
|
||||
local rel = signs(t.tok)
|
||||
assert(rel ~= 0, 'Internal Error: relative label without signs')
|
||||
function Preproc:resolve(t)
|
||||
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 seen = 0
|
||||
local rel = signs(t.tok)
|
||||
assert(rel ~= 0, 'Internal Error: relative label without signs')
|
||||
|
||||
-- TODO: don't iterate over *every* label, just the ones nearby.
|
||||
-- we could do this by popping labels as we pass over them.
|
||||
-- (would need to iterate once forwards and once backwards
|
||||
-- for plus and minus labels respectively)
|
||||
if rel > 0 then
|
||||
for _, rl in ipairs(self.plus_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
|
||||
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
|
||||
local name = t.tok:sub(abs(rel) + 1)
|
||||
local seen = 0
|
||||
|
||||
-- TODO: don't iterate over *every* label, just the ones nearby.
|
||||
-- we could do this by popping labels as we pass over them.
|
||||
-- (would need to iterate once forwards and once backwards
|
||||
-- for plus and minus labels respectively)
|
||||
if rel > 0 then
|
||||
for _, rl in ipairs(self.plus_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
|
||||
|
||||
if seen ~= rel then
|
||||
self:error('could not find appropriate relative label', t.tok)
|
||||
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
|
||||
else
|
||||
return false
|
||||
|
||||
if seen ~= rel then
|
||||
self:error('could not find appropriate relative label', t.tok)
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function Preproc:check(s, i, tt)
|
||||
|
@ -115,7 +114,6 @@ function Preproc:process(statements)
|
|||
self.variables = {}
|
||||
self.plus_labels = {} -- constructed forwards
|
||||
self.minus_labels = {} -- constructed backwards
|
||||
self.do_labels = false
|
||||
|
||||
-- first pass: resolve variables and collect relative labels
|
||||
local new_statements = {}
|
||||
|
@ -152,10 +150,9 @@ function Preproc:process(statements)
|
|||
end
|
||||
|
||||
-- second pass: resolve relative labels
|
||||
self.do_labels = true
|
||||
for s in self:iter(new_statements) do
|
||||
for j, t in ipairs(s) do
|
||||
self:lookup(t)
|
||||
self:resolve(t)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue