mirror of
https://github.com/notwa/mm
synced 2024-11-04 22:39:02 -08:00
use relative labels
This commit is contained in:
parent
9a808fdb80
commit
e4ff34e0c0
2 changed files with 77 additions and 26 deletions
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in a new issue