From e4ff34e0c03fe993c3837b0f383f1219568ba7f7 Mon Sep 17 00:00:00 2001 From: Connor Olding Date: Sat, 2 Jan 2016 04:07:18 -0800 Subject: [PATCH] use relative labels --- Lua/inject/lips.lua | 67 ++++++++++++++++++++++++++++++++++++++------ Lua/inject/spawn.asm | 36 ++++++++++++------------ 2 files changed, 77 insertions(+), 26 deletions(-) diff --git a/Lua/inject/lips.lua b/Lua/inject/lips.lua index ca78de1..9929df9 100644 --- a/Lua/inject/lips.lua +++ b/Lua/inject/lips.lua @@ -805,13 +805,20 @@ function Lexer:lex(_yield) self:error('unmatched closing bracket') elseif self.chr == ')' then self:error('unmatched closing parenthesis') - elseif self.chr == '-' then - self:nextc() - local n = self:read_number() - if n then - yield('NUM', -n) + elseif self.chr == '+' or self.chr == '-' then + local sign_chr = self.chr + local sign = sign_chr == '+' and 1 or -1 + local buff = self:read_chars('%'..self.chr) + if #buff == 1 and self.chr == ':' then + self:nextc() + yield('RELLABEL', sign_chr) else - self:error('expected number after minus sign') + local n = self:read_number() + if n then + yield('NUM', sign*n) + else + yield('RELLABELSYM', sign*#buff) + end end else local n = self:read_number() @@ -1323,12 +1330,14 @@ function Parser:tokenize(asm) return t.tt, t.tok, t.fn, t.line end - -- first pass: collect tokens and constants. + -- first pass: collect tokens, constants, and relative labels. -- can't do more because instruction size can depend on a constant's size -- and labels depend on instruction size. -- note however, instruction size does not depend on label size. -- this would cause a recursive problem to solve, -- which is too much for our simple assembler. + local plus_labels = {} -- constructed forwards + local minus_labels = {} -- constructed backwards while true do local tt, tok, fn, line = lex() self.fn = fn @@ -1339,6 +1348,14 @@ function Parser:tokenize(asm) self:error('expected number for define') end self.defines[tok] = tok2 + elseif tt == 'RELLABEL' then + if tok == '+' then + insert(plus_labels, line) + elseif tok == '-' then + insert(minus_labels, 1, line) + else + error('Internal Error: unexpected token for relative label', 1) + end elseif tt == 'EOL' then -- noop elseif tt == 'EOF' then @@ -1350,7 +1367,7 @@ function Parser:tokenize(asm) end end - -- resolve defines + -- resolve defines and relative labels for i, t in ipairs(self.tokens) do self.fn = t.fn self.line = t.line @@ -1360,6 +1377,40 @@ function Parser:tokenize(asm) if t.tok == nil then self:error('undefined define') -- uhhh nice wording end + elseif t.tt == 'RELLABEL' then + t.tt = 'LABEL' + -- exploits the fact that user labels can't begin with a number + -- FIXME: can produce bad results with includes, etc + t.tok = tostring(t.line) + elseif t.tt == 'RELLABELSYM' then + t.tt = 'LABELSYM' + local rel = t.tok + local seen = 0 + -- TODO: don't iterate over *every* label, just the ones nearby + if rel > 0 then + for i, line in ipairs(plus_labels) do + if line > t.line then + seen = seen + 1 + if seen == rel then + t.tok = tostring(line) + break + end + end + end + else + for i, line in ipairs(minus_labels) do + if line < t.line then + seen = seen - 1 + if seen == rel then + t.tok = tostring(line) + break + end + end + end + end + if seen ~= rel then + self:error('could not find appropriate relative label') + end end end end diff --git a/Lua/inject/spawn.asm b/Lua/inject/spawn.asm index ac12094..6c5e09c 100644 --- a/Lua/inject/spawn.asm +++ b/Lua/inject/spawn.asm @@ -20,47 +20,47 @@ lhu t9, @rupees_offset(t0) lw s1, hold_delay andi t4, t2, @button_any - bne t4, r0, no_reset + bne t4, r0, + addi s1, s1, 1 li s1, 0 -no_reset: ++: subi t4, s1, 1 - beq t4, r0, first_time + beq t4, r0, + nop subi t4, s1, @hold_delay_amount bltz t4, return nop -first_time: ++: andi t3, t2, @button_D_up - beq t3, r0, no_D_up + beq t3, r0, + nop addi t9, t9, 1 -no_D_up: ++: andi t3, t2, @button_D_down - beq t3, r0, no_D_down + beq t3, r0, + nop subi t9, t9, 1 -no_D_down: ++: andi t3, t2, @button_D_right - beq t3, r0, no_D_right + beq t3, r0, + nop addi t9, t9, 10 -no_D_right: ++: andi t3, t2, @button_D_left - beq t3, r0, no_D_left + beq t3, r0, + nop subi t9, t9, 10 -no_D_left: ++: subi t4, t9, 1 - bgez t4, no_min + bgez t4, + nop li t9, @max_actor_no -no_min: ++: subi t4, t9, @max_actor_no - blez t4, no_max + blez t4, + nop li t9, 1 -no_max: ++: sh t9, @rupees_offset(t0) andi t3, t2, @button_L beq t3, r0, return @@ -162,12 +162,12 @@ is_object_loaded: add t0, t8, t9 // current item lb t1, 8(t0) // remaining items li v0, 1 -is_object_loaded_loop: +-: lh t2, 12(t0) // item's object number beq a0, t2, is_object_loaded_return subi t1, t1, 1 // TODO: double check there's no off-by-one error addi t0, t0, 68 - bne t1, r0, is_object_loaded_loop + bne t1, r0, - nop cl v0 is_object_loaded_return: