1
0
Fork 0
mirror of https://github.com/notwa/mm synced 2024-11-04 22:39:02 -08:00

use relative labels

This commit is contained in:
Connor Olding 2016-01-02 04:07:18 -08:00
parent 9a808fdb80
commit e4ff34e0c0
2 changed files with 77 additions and 26 deletions

View file

@ -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

View file

@ -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: