From 437b816f858e1bd4fc549d722903ae5407829bcd Mon Sep 17 00:00:00 2001 From: Connor Olding Date: Sun, 27 Nov 2016 16:17:32 -0800 Subject: [PATCH] refactor label resolution into its own method --- lips/Preproc.lua | 85 +++++++++++++++++++++++------------------------- 1 file changed, 41 insertions(+), 44 deletions(-) diff --git a/lips/Preproc.lua b/lips/Preproc.lua index a4a9137..89e136e 100644 --- a/lips/Preproc.lua +++ b/lips/Preproc.lua @@ -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