1
0
Fork 0
mirror of https://github.com/notwa/lips synced 2024-05-21 09:33:23 -07:00

implement incbin directive

This commit is contained in:
Connor Olding 2016-04-10 04:03:00 -07:00
parent 5afb743977
commit a58ad83c92
4 changed files with 34 additions and 10 deletions

View File

@ -237,6 +237,11 @@ include an external assembly file as-is at this position.
lips will look for the included file lips will look for the included file
in the directory of the file using the directive. in the directory of the file using the directive.
* `.incbin {filename}`
write an external binary file as-is at this position.
lips will look for the included file
in the directory of the file using the directive.
* `.ascii "some\ntext\0"` * `.ascii "some\ntext\0"`
writes a string using its characters' ASCII values. writes a string using its characters' ASCII values.
a few escapes are currently supported: `\ " a b f n r t v 0` a few escapes are currently supported: `\ " a b f n r t v 0`
@ -249,5 +254,3 @@ same as ascii, but with a null byte added to the end.
* FLOAT: writes a list of 32-bit floating point numbers until end-of-line. * FLOAT: writes a list of 32-bit floating point numbers until end-of-line.
this may not get implemented due to a lack of aliasing in vanilla Lua, this may not get implemented due to a lack of aliasing in vanilla Lua,
and thus accuracy issues. and thus accuracy issues.
* INCBIN: write an external binary file as-is at this position.

View File

@ -278,6 +278,24 @@ function Lexer:lex_include(_yield)
sublexer:lex(_yield) sublexer:lex(_yield)
end end
function Lexer:lex_include_binary(_yield)
self:read_spaces()
local fn
self:lex_string_naive(function(tt, tok)
fn = tok
end)
if self.options.path then
fn = self.options.path..fn
end
-- NOTE: this allocates two tables for each byte.
-- this could easily cause performance issues on big files.
local data = util.readfile(fn, true)
for b in string.gfind(data, '.') do
_yield('DIR', 'BYTE', fn, 0)
_yield('NUM', string.byte(b), fn, 0)
end
end
function Lexer:lex(_yield) function Lexer:lex(_yield)
local function yield(tt, tok) local function yield(tt, tok)
return _yield(tt, tok, self.fn, self.line) return _yield(tt, tok, self.fn, self.line)
@ -338,6 +356,9 @@ function Lexer:lex(_yield)
if up == 'INC' or up == 'INCASM' or up == 'INCLUDE' then if up == 'INC' or up == 'INCASM' or up == 'INCLUDE' then
yield('DIR', 'INC') yield('DIR', 'INC')
self:lex_include(_yield) self:lex_include(_yield)
elseif up == 'INCBIN' then
yield('DIR', 'INCBIN')
self:lex_include_binary(_yield)
else else
yield('DIR', up) yield('DIR', up)
end end

View File

@ -54,7 +54,7 @@ function Parser:directive()
add(name, self:const().tok) add(name, self:const().tok)
end end
self:expect_EOL() self:expect_EOL()
elseif name == 'INC' then elseif name == 'INC' or name == 'INCBIN' then
-- noop, handled by lexer -- noop, handled by lexer
elseif name == 'ASCII' or name == 'ASCIIZ' then elseif name == 'ASCII' or name == 'ASCIIZ' then
local bytes = self:string() local bytes = self:string()
@ -65,8 +65,6 @@ function Parser:directive()
add('BYTE', 0) add('BYTE', 0)
end end
self:expect_EOL() self:expect_EOL()
elseif name == 'INCBIN' then
self:error('unimplemented')
elseif name == 'FLOAT' then elseif name == 'FLOAT' then
self:error('unimplemented') self:error('unimplemented')
else else

View File

@ -16,14 +16,16 @@ local function Class(inherit)
return setmetatable(class, mt_class) return setmetatable(class, mt_class)
end end
local function readfile(fn) local function readfile(fn, binary)
local f = open(fn, 'r') local mode = binary and 'rb' or 'r'
local f = open(fn, mode)
if not f then if not f then
error('could not open assembly file for reading: '..tostring(fn), 2) local kind = binary and 'binary' or 'assembly'
error('could not open '..kind..' file for reading: '..tostring(fn), 2)
end end
local asm = f:read('*a') local data = f:read('*a')
f:close() f:close()
return asm return data
end end
local function bitrange(x, lower, upper) local function bitrange(x, lower, upper)