1
0
Fork 0
mirror of https://github.com/notwa/mm synced 2024-11-05 05:49:02 -08:00
alias ZERO register to R0.
lex decimal numbers properly.
lex octal and negative numbers.
lex directives properly.
fix byte dumping.
fix UPPER behavior...?
This commit is contained in:
Connor Olding 2015-11-21 15:04:30 -08:00
parent 39ffd10fff
commit 5397085f01

View file

@ -76,6 +76,11 @@ end
revtable(registers) revtable(registers)
revtable(fpu_registers) revtable(fpu_registers)
revtable(all_registers) revtable(all_registers)
revtable(all_directives)
registers['ZERO'] = 0
all_registers['ZERO'] = 0
local fmt_single = 16 local fmt_single = 16
local fmt_double = 17 local fmt_double = 17
@ -333,6 +338,7 @@ local instruction_handlers = {
-- ...that expand to multiple instructions -- ...that expand to multiple instructions
LI = {}, -- only one instruction for values < 0x10000 LI = {}, -- only one instruction for values < 0x10000
LA = {}, -- alias for li
BEQI = {}, BEQI = {},
BNEI = {}, BNEI = {},
@ -437,28 +443,32 @@ function Lexer:read_chars(pattern)
end end
end end
function Lexer:read_number() function Lexer:read_decimal()
self.buff = '' self.buff = ''
self:nextc()
self:read_chars('%d') self:read_chars('%d')
local num = tonumber(self.buff) local num = tonumber(self.buff)
if not num then self:error('invalid number') end if not num then self:error('invalid decimal number') end
return num return num
end end
function Lexer:read_hex() function Lexer:read_hex()
self.buff = '' self.buff = ''
if self.chr ~= '$' then self:nextc() end
self:nextc()
self:read_chars('%x') self:read_chars('%x')
local num = tonumber(self.buff, 16) local num = tonumber(self.buff, 16)
if not num then self:error('invalid hex number') end if not num then self:error('invalid hex number') end
return num return num
end end
function Lexer:read_octal()
self.buff = ''
self:read_chars('[0-7]')
local num = tonumber(self.buff)
if not num then self:error('invalid octal number') end
return num
end
function Lexer:read_binary() function Lexer:read_binary()
self.buff = '' self.buff = ''
self:nextc()
self:read_chars('[01]') self:read_chars('[01]')
local num = tonumber(self.buff, 2) local num = tonumber(self.buff, 2)
if not num then self:error('invalid binary number') end if not num then self:error('invalid binary number') end
@ -481,6 +491,30 @@ function Lexer:skip_block_comment()
end end
end end
function Lexer:read_number()
if self.chr == '%' then
self:nextc()
return self:read_binary()
elseif self.chr == '$' then
self:nextc()
return self:read_hex()
elseif self.chr:find('%d') then
if self.chr2 == 'x' or self.chr2 == 'X' then
self:nextc()
self:nextc()
return self:read_hex()
elseif self.chr == '0' and self.chr2:find('%d') then
self:nextc()
return self:read_octal_number()
else
return self:read_decimal()
end
elseif self.chr == '#' then
self:nextc()
return self:read_decimal()
end
end
function Lexer:lex() function Lexer:lex()
while true do while true do
if self.chr == '\n' then if self.chr == '\n' then
@ -496,16 +530,6 @@ function Lexer:lex()
self:skip_block_comment() self:skip_block_comment()
elseif self.chr:find('%s') then elseif self.chr:find('%s') then
self:nextc() self:nextc()
elseif self.chr == '$' then
return 'NUM', self:read_hex()
elseif self.chr == '%' then
return 'NUM', self:read_binary()
elseif self.chr:find('%d') then
-- TODO: check if cajaasm accepts 0X0
if self.chr2 == 'x' or self.chr2 == 'X' then
return 'NUM', self:read_hex()
end
return 'NUM', self:read_number()
elseif self.chr == ',' then elseif self.chr == ',' then
self:nextc() self:nextc()
return 'SEP', ',' return 'SEP', ','
@ -537,6 +561,7 @@ function Lexer:lex()
return 'DEREF', up return 'DEREF', up
elseif self.chr == '.' then elseif self.chr == '.' then
self.buff = '' self.buff = ''
self:nextc()
self:read_chars('[%w]') self:read_chars('[%w]')
local up = self.buff:upper() local up = self.buff:upper()
if not all_directives[up] then if not all_directives[up] then
@ -578,7 +603,19 @@ function Lexer:lex()
self:error('unmatched closing bracket') self:error('unmatched closing bracket')
elseif self.chr == ')' then elseif self.chr == ')' then
self:error('unmatched closing parenthesis') self:error('unmatched closing parenthesis')
elseif self.chr == '-' then
self:nextc()
local n = self:read_number()
if n then
return 'NUM', -n
else else
self:error('expected number after minus sign')
end
else
local n = self:read_number()
if n then
return 'NUM', n
end
self:error('unknown character or control character') self:error('unknown character or control character')
end end
end end
@ -876,7 +913,7 @@ function Dumper:add_bytes(bs)
end end
for _, b in ipairs(bs) do for _, b in ipairs(bs) do
t.size = t.size + 1 t.size = t.size + 1
t[size] = b t[t.size] = b
end end
if not use_last then if not use_last then
table.insert(self.commands, t) table.insert(self.commands, t)
@ -963,10 +1000,7 @@ function Dumper:toval(tok)
end end
if tok[1] == 'UPPER' then if tok[1] == 'UPPER' then
local val = self:desym(tok[2]) local val = self:desym(tok[2])
-- this could cause some unexpected behaviors val = math.floor(val/0x10000)
while val >= 0x10000 do
val = val/2
end
return val return val
elseif tok[1] == 'LOWER' then elseif tok[1] == 'LOWER' then
local val = self:desym(tok[2]) local val = self:desym(tok[2])