mirror of
https://github.com/notwa/mm
synced 2025-02-05 05:23:22 -08:00
update lips
This commit is contained in:
parent
bd6cf49f6b
commit
d403d52ad5
6 changed files with 89 additions and 28 deletions
|
@ -31,6 +31,8 @@ function Expander:pop(kind)
|
||||||
ret = self.s[self.i]
|
ret = self.s[self.i]
|
||||||
elseif kind == 'CPU' then
|
elseif kind == 'CPU' then
|
||||||
ret = self:register(data.registers)
|
ret = self:register(data.registers)
|
||||||
|
elseif kind == 'FPU' then
|
||||||
|
ret = self:register(data.fpu_registers)
|
||||||
elseif kind == 'DEREF' then
|
elseif kind == 'DEREF' then
|
||||||
ret = self:deref()
|
ret = self:deref()
|
||||||
elseif kind == 'CONST' then
|
elseif kind == 'CONST' then
|
||||||
|
|
|
@ -144,22 +144,39 @@ function Expression:lex1(str, tokens)
|
||||||
local here = " (#"..tostring(pos)..")"
|
local here = " (#"..tostring(pos)..")"
|
||||||
if consider(' +') then
|
if consider(' +') then
|
||||||
consume(#considered)
|
consume(#considered)
|
||||||
elseif consider('[0-9.]') then
|
elseif consider('[0-9.]') or consider('[%%$#]') then
|
||||||
local num
|
local num
|
||||||
if consider('((0|[1-9][0-9]*)%.[0-9]*|%.[0-9]+)(e0|e[1-9][0-9]*)?') then
|
if consider('((0|[1-9][0-9]*)%.[0-9]*|%.[0-9]+)(e0|e[1-9][0-9]*)?') then
|
||||||
num = tonumber(considered)
|
num = tonumber(considered)
|
||||||
elseif consider('(0|[1-9][0-9]*)e(0|[1-9][0-9]*)') then
|
elseif consider('(0|[1-9][0-9]*)e(0|[1-9][0-9]*)') then
|
||||||
num = tonumber(considered)
|
num = tonumber(considered)
|
||||||
elseif consider('[0-1]+b') then
|
elseif consider('%%[0-9]+') then
|
||||||
num = tonumber(considered, 2)
|
if considered:match('[2-9]') then
|
||||||
|
return "bad binary number: "..considered..here
|
||||||
|
end
|
||||||
|
num = tonumber(considered:sub(2), 2)
|
||||||
|
elseif consider('$[0-9A-Fa-f]+') then
|
||||||
|
num = tonumber(considered:sub(2), 16)
|
||||||
elseif consider('0x[0-9A-Fa-f]+') then
|
elseif consider('0x[0-9A-Fa-f]+') then
|
||||||
num = tonumber(considered, 16)
|
num = tonumber(considered:sub(3), 16)
|
||||||
|
elseif consider('0o[0-9]+') then
|
||||||
|
if considered:match('[89]') then
|
||||||
|
return "bad octal number: "..considered..here
|
||||||
|
end
|
||||||
|
num = tonumber(considered:sub(3), 8)
|
||||||
|
elseif consider('0b[0-9]+') then
|
||||||
|
if considered:match('[2-9]') then
|
||||||
|
return "bad binary number: "..considered..here
|
||||||
|
end
|
||||||
|
num = tonumber(considered:sub(3), 2)
|
||||||
elseif consider('0[0-9]+') then
|
elseif consider('0[0-9]+') then
|
||||||
if considered:match('[89]') then
|
if considered:match('[89]') then
|
||||||
return "bad octal number: "..considered..here
|
return "bad octal number: "..considered..here
|
||||||
end
|
end
|
||||||
num = tonumber(considered, 8)
|
num = tonumber(considered:sub(2), 8)
|
||||||
elseif consider('[0-9]*') then
|
elseif consider('#[0-9]+') then
|
||||||
|
num = tonumber(considered:sub(2))
|
||||||
|
elseif consider('[0-9]+') then
|
||||||
num = tonumber(considered)
|
num = tonumber(considered)
|
||||||
end
|
end
|
||||||
if num == nil then
|
if num == nil then
|
||||||
|
@ -176,7 +193,7 @@ function Expression:lex1(str, tokens)
|
||||||
elseif consider_operator() then
|
elseif consider_operator() then
|
||||||
insert(tokens, {type='operator', value=considered})
|
insert(tokens, {type='operator', value=considered})
|
||||||
consume(#considered)
|
consume(#considered)
|
||||||
elseif consider('%w+') then
|
elseif consider('[%w_]+') then
|
||||||
local num = self.variables[considered]
|
local num = self.variables[considered]
|
||||||
if num == nil then
|
if num == nil then
|
||||||
return 'undefined variable "'..considered..'"'
|
return 'undefined variable "'..considered..'"'
|
||||||
|
|
|
@ -3,6 +3,7 @@ local char = string.char
|
||||||
local find = string.find
|
local find = string.find
|
||||||
local format = string.format
|
local format = string.format
|
||||||
local insert = table.insert
|
local insert = table.insert
|
||||||
|
local unpack = rawget(_G, 'unpack') or table.unpack
|
||||||
|
|
||||||
local path = string.gsub(..., "[^.]+$", "")
|
local path = string.gsub(..., "[^.]+$", "")
|
||||||
local data = require(path.."data")
|
local data = require(path.."data")
|
||||||
|
@ -15,6 +16,7 @@ local simple_escapes = {
|
||||||
['"'] = 0x22,
|
['"'] = 0x22,
|
||||||
['a'] = 0x07,
|
['a'] = 0x07,
|
||||||
['b'] = 0x08,
|
['b'] = 0x08,
|
||||||
|
['e'] = 0x1B,
|
||||||
['f'] = 0x0C,
|
['f'] = 0x0C,
|
||||||
['n'] = 0x0A,
|
['n'] = 0x0A,
|
||||||
['r'] = 0x0D,
|
['r'] = 0x0D,
|
||||||
|
@ -263,6 +265,18 @@ function Lexer:lex_string(yield)
|
||||||
local simple = simple_escapes[self.chr]
|
local simple = simple_escapes[self.chr]
|
||||||
if simple then
|
if simple then
|
||||||
insert(bytes, simple)
|
insert(bytes, simple)
|
||||||
|
elseif self.chr == 'x' then
|
||||||
|
self:nextc()
|
||||||
|
local hex = self.chrchr
|
||||||
|
if not self.chr:find('[0-9a-fA-F]') then
|
||||||
|
self:error('invalid hex escape sequence: \\x'..hex)
|
||||||
|
end
|
||||||
|
self:nextc()
|
||||||
|
if not self.chr:find('[0-9a-fA-F]') then
|
||||||
|
self:error('invalid hex escape sequence: \\x'..hex)
|
||||||
|
end
|
||||||
|
local byte = tonumber(hex, 16)
|
||||||
|
insert(bytes, byte)
|
||||||
else
|
else
|
||||||
self:error('unknown escape sequence')
|
self:error('unknown escape sequence')
|
||||||
end
|
end
|
||||||
|
@ -276,32 +290,27 @@ function Lexer:lex_string(yield)
|
||||||
yield('STRING', bytes)
|
yield('STRING', bytes)
|
||||||
end
|
end
|
||||||
|
|
||||||
function Lexer:lex_string_naive(yield) -- no escape sequences
|
|
||||||
if self.chr ~= '"' then
|
|
||||||
self:error('expected opening double quote')
|
|
||||||
end
|
|
||||||
self:nextc()
|
|
||||||
local buff = self:read_chars('[^"\n]')
|
|
||||||
if self.chr ~= '"' then
|
|
||||||
self:error('expected closing double quote')
|
|
||||||
end
|
|
||||||
self:nextc()
|
|
||||||
yield('STRING', buff)
|
|
||||||
end
|
|
||||||
|
|
||||||
function Lexer:lex_filename(_yield)
|
function Lexer:lex_filename(_yield)
|
||||||
self:read_spaces()
|
self:read_spaces()
|
||||||
local fn
|
local fn = ''
|
||||||
self:lex_string_naive(function(tt, tok)
|
self:lex_string(function(tt, tok)
|
||||||
fn = tok
|
fn = char(unpack(tok))
|
||||||
end)
|
end)
|
||||||
_yield('STRING', fn, self.fn, self.line)
|
_yield('STRING', fn, self.fn, self.line)
|
||||||
|
|
||||||
if self.chr ~= '\n' then
|
self:read_spaces()
|
||||||
|
if self.chr == ';' or self.chrchr == '//' then
|
||||||
|
self:skip_to_EOL()
|
||||||
|
end
|
||||||
|
if self.chr == '\n' then
|
||||||
|
_yield('EOL', '\n', self.fn, self.line)
|
||||||
|
self:nextc()
|
||||||
|
elseif self.ord == self.EOF then
|
||||||
|
_yield('EOL', '\n', self.fn, self.line)
|
||||||
|
self.was_EOL = true
|
||||||
|
else
|
||||||
self:error('expected EOL after filename')
|
self:error('expected EOL after filename')
|
||||||
end
|
end
|
||||||
_yield('EOL', '\n', self.fn, self.line)
|
|
||||||
self:nextc()
|
|
||||||
|
|
||||||
return fn
|
return fn
|
||||||
end
|
end
|
||||||
|
|
|
@ -184,7 +184,8 @@ function TokenIter:special()
|
||||||
|
|
||||||
local args = {}
|
local args = {}
|
||||||
while true do
|
while true do
|
||||||
local arg = self:advance()
|
self:advance()
|
||||||
|
local arg = self.t
|
||||||
if not self.arg_types[arg.tt] then
|
if not self.arg_types[arg.tt] then
|
||||||
self:error('invalid argument type', arg.tt)
|
self:error('invalid argument type', arg.tt)
|
||||||
else
|
else
|
||||||
|
|
|
@ -49,9 +49,10 @@ end
|
||||||
local overrides = {}
|
local overrides = {}
|
||||||
-- note: "self" is an instance of Expander
|
-- note: "self" is an instance of Expander
|
||||||
|
|
||||||
|
local fpu_tob = {}
|
||||||
local function tob_override(self, name)
|
local function tob_override(self, name)
|
||||||
-- handle all the addressing modes for lw/sw-like instructions
|
-- handle all the addressing modes for lw/sw-like instructions
|
||||||
local dest = self:pop('CPU')
|
local dest = fpu_tob[name] and self:pop('FPU') or self:pop('CPU')
|
||||||
local offset, base
|
local offset, base
|
||||||
if self:peek('DEREF') then
|
if self:peek('DEREF') then
|
||||||
offset = 0
|
offset = 0
|
||||||
|
@ -96,6 +97,9 @@ end
|
||||||
for k, v in pairs(data.instructions) do
|
for k, v in pairs(data.instructions) do
|
||||||
if v[2] == 'tob' then
|
if v[2] == 'tob' then
|
||||||
overrides[k] = tob_override
|
overrides[k] = tob_override
|
||||||
|
elseif v[2] == 'Tob' then
|
||||||
|
fpu_tob[k] = true
|
||||||
|
overrides[k] = tob_override
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -82,4 +82,32 @@ function writers.make_tester()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function writers.make_gameshark()
|
||||||
|
local buff = {}
|
||||||
|
local max = -1
|
||||||
|
return function(pos, b)
|
||||||
|
if pos then
|
||||||
|
pos = pos % 0x80000000
|
||||||
|
buff[pos] = b
|
||||||
|
if pos > max then
|
||||||
|
max = pos
|
||||||
|
end
|
||||||
|
elseif max >= 0 then
|
||||||
|
for i=0, max, 2 do
|
||||||
|
local a = buff[i+0]
|
||||||
|
local b = buff[i+1]
|
||||||
|
a = a and ("%02X"):format(a)
|
||||||
|
b = b and ("%02X"):format(b)
|
||||||
|
if a and b then
|
||||||
|
print(('81%06X %s'):format(i, a..b))
|
||||||
|
elseif a then
|
||||||
|
print(('80%06X 00%s'):format(i, a))
|
||||||
|
elseif b then
|
||||||
|
print(('80%06X 00%s'):format(i + 1, b))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
return writers
|
return writers
|
||||||
|
|
Loading…
Add table
Reference in a new issue