1
0
Fork 0
mirror of https://github.com/notwa/lips synced 2024-11-14 09:39:03 -08: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
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"`
writes a string using its characters' ASCII values.
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.
this may not get implemented due to a lack of aliasing in vanilla Lua,
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)
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)
local function yield(tt, tok)
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
yield('DIR', 'INC')
self:lex_include(_yield)
elseif up == 'INCBIN' then
yield('DIR', 'INCBIN')
self:lex_include_binary(_yield)
else
yield('DIR', up)
end

View file

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

View file

@ -16,14 +16,16 @@ local function Class(inherit)
return setmetatable(class, mt_class)
end
local function readfile(fn)
local f = open(fn, 'r')
local function readfile(fn, binary)
local mode = binary and 'rb' or 'r'
local f = open(fn, mode)
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
local asm = f:read('*a')
local data = f:read('*a')
f:close()
return asm
return data
end
local function bitrange(x, lower, upper)