diff --git a/lips/Dumper.lua b/lips/Dumper.lua index ab86ac8..ecf29b6 100644 --- a/lips/Dumper.lua +++ b/lips/Dumper.lua @@ -80,11 +80,17 @@ function Dumper:add_directive(line, name, a, b) local b1 = bitrange(a, 8, 15) self:add_bytes(line, b1, b0) elseif name == 'WORD' then - local b0 = bitrange(a, 0, 7) - local b1 = bitrange(a, 8, 15) - local b2 = bitrange(a, 16, 23) - local b3 = bitrange(a, 24, 31) - self:add_bytes(line, b3, b2, b1, b0) + if type(a) == 'string' then + local t = {line=line, kind='label', name=a} + insert(self.commands, t) + self:advance(4) + else + local b0 = bitrange(a, 0, 7) + local b1 = bitrange(a, 8, 15) + local b2 = bitrange(a, 16, 23) + local b3 = bitrange(a, 24, 31) + self:add_bytes(line, b3, b2, b1, b0) + end elseif name == 'ORG' then t.kind = 'goto' t.addr = a @@ -271,8 +277,16 @@ function Dumper:dump() else self.pos = self.pos + t.skip end + elseif t.kind == 'label' then + local val = self:desym{'LABELSYM', t.name} + val = (val % 0x80000000) + 0x80000000 + local b0 = bitrange(val, 0, 7) + local b1 = bitrange(val, 8, 15) + local b2 = bitrange(val, 16, 23) + local b3 = bitrange(val, 24, 31) + self:write{b3, b2, b1, b0} else - error('Internal Error: unknown command', 1) + error('Internal Error: unknown command') end end end diff --git a/lips/Lexer.lua b/lips/Lexer.lua index 2e5d1af..cddb130 100644 --- a/lips/Lexer.lua +++ b/lips/Lexer.lua @@ -221,7 +221,6 @@ function Lexer:lex_block_comment(yield) end function Lexer:lex_string(yield) - -- TODO: support escaping if self.chr ~= '"' then self:error('expected opening double quote') end diff --git a/lips/Parser.lua b/lips/Parser.lua index 528abc8..2e2bb83 100644 --- a/lips/Parser.lua +++ b/lips/Parser.lua @@ -85,7 +85,7 @@ function Parser:directive() end self:expect_EOL() end - elseif name == 'BYTE' or name == 'HALFWORD' or name == 'WORD' then + elseif name == 'BYTE' or name == 'HALFWORD' then self.dumper:add_directive(line, name, self:number()) while not self:is_EOL() do self:advance() @@ -93,6 +93,14 @@ function Parser:directive() self.dumper:add_directive(line, name, self:number()) end self:expect_EOL() + elseif name == 'WORD' then -- allow labels in word directives + self.dumper:add_directive(line, name, self:const()[2]) + while not self:is_EOL() do + self:advance() + self:optional_comma() + self.dumper:add_directive(line, name, self:const()[2]) + end + self:expect_EOL() elseif name == 'INC' then -- noop, handled by lexer elseif name == 'ASCII' or name == 'ASCIIZ' then