local require,table = require,table module((...)) local parse = require(_PACKAGE.."parser") local gen = {} gen.preamble = [[ local fd,data = ... local stack = {} local index = 1 local start = fd:seek() local len = 0 local function push(key) if not key then key = index index = index + 1 end stack[#stack+1] = { index, data } data = data[key] index = 1 end local function pop(key) local saved = stack[#stack] stack[#stack] = nil index = saved[1] data = saved[2] 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 fd,len ]] -- control: -- <>(fd, <>) 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: -- <>(fd, data[index], <>) -- ++index function gen.atom(token) local fn = token[1] local args = token[2]:gsub('%.', ', ') if #args == 0 then args = "nil" end return fn.."(fd, data[index], "..args..")\nindex = index+1" end -- table: -- push() -- <> -- pop() function gen.table(token) return "push()\n" ..parse(token[1]:sub(2,-2), gen) .."\npop()" end -- group: -- <> function gen.group(token) return parse(token[1]:sub(2,-2), gen) end -- named atom: -- <>(fd, data.<>, <>) function gen.name_atom(token) local fn = token[2] local args = token[3]:gsub('%.', ', ') if #args == 0 then args = "nil" end return fn.."(fd, data."..token[1]..", "..args..")" end -- named table: -- push(<>) -- <
> -- pop() function gen.name_table(token) return "push('"..token[1].."')\n" ..parse(token[2]:sub(2,-2), gen) .."\npop()" 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