2016-01-13 09:51:29 -08:00
|
|
|
local lips = {
|
2015-11-20 16:21:13 -08:00
|
|
|
_DESCRIPTION = 'Assembles MIPS assembly files for the R4300i CPU.',
|
2015-11-23 14:16:31 -08:00
|
|
|
_URL = 'https://github.com/notwa/lips/',
|
2015-11-20 16:21:13 -08:00
|
|
|
_LICENSE = [[
|
2016-01-13 06:30:58 -08:00
|
|
|
Copyright (C) 2015,2016 Connor Olding
|
2015-11-20 16:21:13 -08:00
|
|
|
|
|
|
|
This program is licensed under the terms of the MIT License, and
|
|
|
|
is distributed without any warranty. You should have received a
|
|
|
|
copy of the license along with this program; see the file LICENSE.
|
|
|
|
]],
|
|
|
|
}
|
|
|
|
|
2016-04-14 07:33:33 -07:00
|
|
|
local path = string.gsub(..., "%.init$", "").."."
|
|
|
|
local util = require(path.."util")
|
|
|
|
local Parser = require(path.."Parser")
|
2015-12-02 09:09:44 -08:00
|
|
|
|
2016-04-26 21:34:05 -07:00
|
|
|
lips.writers = require(path.."writers")
|
2015-11-20 11:53:09 -08:00
|
|
|
|
2016-01-13 09:51:29 -08:00
|
|
|
function lips.assemble(fn_or_asm, writer, options)
|
2015-11-23 14:16:31 -08:00
|
|
|
-- assemble MIPS R4300i assembly code.
|
|
|
|
-- if fn_or_asm contains a newline; treat as assembly, otherwise load file.
|
|
|
|
-- returns error message on error, or nil on success.
|
2015-11-20 16:21:13 -08:00
|
|
|
fn_or_asm = tostring(fn_or_asm)
|
2015-12-25 01:09:00 -08:00
|
|
|
local default_writer = not writer
|
2016-04-26 21:34:05 -07:00
|
|
|
writer = writer or lips.writers.make_word()
|
2015-11-26 19:45:13 -08:00
|
|
|
options = options or {}
|
2015-11-20 14:00:02 -08:00
|
|
|
|
2016-01-13 07:16:41 -08:00
|
|
|
local function main()
|
2016-04-21 12:56:13 -07:00
|
|
|
if options.offset then
|
|
|
|
if options.origin or options.base then
|
|
|
|
error('offset and origin/base options are mutually exclusive')
|
|
|
|
end
|
|
|
|
io.stderr:write('Warning: options.offset is deprecated.\n')
|
|
|
|
options.origin = options.offset
|
|
|
|
options.base = 0
|
|
|
|
else
|
2016-04-23 19:36:26 -07:00
|
|
|
options.origin = options.origin or 0
|
2016-04-21 12:56:13 -07:00
|
|
|
options.base = options.base or 0x80000000
|
|
|
|
end
|
|
|
|
|
2015-11-21 17:35:43 -08:00
|
|
|
local fn = nil
|
2015-12-18 23:42:54 -08:00
|
|
|
local asm
|
2015-11-20 16:21:13 -08:00
|
|
|
if fn_or_asm:find('[\r\n]') then
|
|
|
|
asm = fn_or_asm
|
|
|
|
else
|
2015-11-21 17:35:43 -08:00
|
|
|
fn = fn_or_asm
|
2016-01-15 11:15:02 -08:00
|
|
|
asm = util.readfile(fn)
|
2015-12-18 23:42:54 -08:00
|
|
|
options.path = fn:match(".*/")
|
2015-11-20 16:21:13 -08:00
|
|
|
end
|
|
|
|
|
2015-12-17 07:19:24 -08:00
|
|
|
local parser = Parser(writer, fn, options)
|
2015-12-25 01:09:00 -08:00
|
|
|
parser:parse(asm)
|
|
|
|
|
|
|
|
if default_writer then
|
|
|
|
writer()
|
|
|
|
end
|
2015-11-20 15:27:22 -08:00
|
|
|
end
|
2015-11-20 11:53:09 -08:00
|
|
|
|
2015-11-26 19:45:13 -08:00
|
|
|
if options.unsafe then
|
2015-11-24 17:06:38 -08:00
|
|
|
return main()
|
|
|
|
else
|
|
|
|
local ok, err = pcall(main)
|
|
|
|
return err
|
|
|
|
end
|
2015-11-20 11:53:09 -08:00
|
|
|
end
|
2015-11-20 16:21:13 -08:00
|
|
|
|
2016-01-13 09:51:29 -08:00
|
|
|
return setmetatable(lips, {
|
2015-11-26 19:45:13 -08:00
|
|
|
__call = function(self, ...)
|
|
|
|
return self.assemble(...)
|
2015-11-20 16:21:13 -08:00
|
|
|
end,
|
|
|
|
})
|