luaforwindows/files/lua/vstruct/gen_unpack.lua

118 lines
2.1 KiB
Lua
Executable File

local require,table
= require,table
module((...))
local parse = require(_PACKAGE.."parser")
local gen = {}
gen.preamble = [[
local fd = (...)
local stack = {}
local pack = {}
local start = fd:seek()
local len = 0
local function push()
stack[#stack+1],pack = pack,{}
end
local function pop(key)
local target = stack[#stack]
key = key or #target+1
target[key],pack = pack,target
stack[#stack] = nil
end
local function update_len()
len = len + fd:seek() - start
end
local function update_start()
start = fd:seek()
end
hostendian()
]]
gen.postamble = [[
update_len()
return pack,len
]]
-- control:
-- <<type>>(fd, <<args>>)
function gen.control(token)
local tr = {
["<"] = "littleendian";
[">"] = "bigendian";
["="] = "hostendian";
["+"] = "seekforward";
["-"] = "seekback";
["@"] = "seekto";
}
local fn = tr[token[1]] or token[1]
local args = token[2]:gsub('%.', ', ')
if #args == 0 then args = "nil" end
return "update_len(); "..fn.."(fd, "..args..")".."; update_start()"
end
-- atom:
-- pack[#pack+1] = <<type>>(fd, <<args>>)
function gen.atom(token)
local fn = token[1]
local args = token[2]:gsub('%.', ', ')
if #args == 0 then args = "nil" end
return "pack[#pack+1] = "..fn.."(fd, "..args..")"
end
-- table:
-- push()
-- <<table contents>>
-- pop()
function gen.table(token)
return "push()\n"
..parse(token[1]:sub(2,-2), gen)
.."\npop()"
end
-- group:
-- <<group contents>>
function gen.group(token)
return parse(token[1]:sub(2,-2), gen)
end
function gen.name_atom(token)
local fn = token[2]
local args = token[3]:gsub('%.', ', ')
if #args == 0 then args = "nil" end
return "pack."..token[1].." = "..fn.."(fd, "..args..")"
end
function gen.name_table(token)
return "push()\n"
..parse(token[2]:sub(2,-2), gen)
.."\npop('"..token[1].."')\n"
end
function gen.prerepeat(token, get)
local next = get()
local src = gen[next.type](next, get)
return "for _idx=1,"..token[1].." do\n\n"..src.."\nend"
end
function gen.postrepeat(token, get, asl)
local src = table.remove(asl)
return "for _idx=1,"..token[1].." do\n\n"..src.."\nend"
end
return gen