Sat, 01 Nov 2014 23:34:21 +0000
Lua 5.2 compatibility hack
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/compat_env.lua Sat Nov 01 23:34:21 2014 +0000 @@ -0,0 +1,144 @@ +--[[ + compat_env - see README for details. + (c) 2012 David Manura. Licensed under Lua 5.1/5.2 terms (MIT license). +--]] + +local M = {_TYPE='module', _NAME='compat_env', _VERSION='0.2.2.20120406'} + +local function check_chunk_type(s, mode) + local nmode = mode or 'bt' + local is_binary = s and #s > 0 and s:byte(1) == 27 + if is_binary and not nmode:match'b' then + return nil, ("attempt to load a binary chunk (mode is '%s')"):format(mode) + elseif not is_binary and not nmode:match't' then + return nil, ("attempt to load a text chunk (mode is '%s')"):format(mode) + end + return true +end + +local IS_52_LOAD = pcall(load, '') +if IS_52_LOAD then + M.load = _G.load + M.loadfile = _G.loadfile +else + -- 5.2 style `load` implemented in 5.1 + function M.load(ld, source, mode, env) + local f + if type(ld) == 'string' then + local s = ld + local ok, err = check_chunk_type(s, mode) + if not ok then return ok, err end + local err; f, err = loadstring(s, source) + if not f then return f, err end + elseif type(ld) == 'function' then + local ld2 = ld + if (mode or 'bt') ~= 'bt' then + local first = ld() + local ok, err = check_chunk_type(first, mode) + if not ok then return ok, err end + ld2 = function() + if first then + local chunk=first; first=nil; return chunk + else return ld() end + end + end + local err; f, err = load(ld2, source); if not f then return f, err end + else + error(("bad argument #1 to 'load' (function expected, got %s)") + :format(type(ld)), 2) + end + if env then setfenv(f, env) end + return f + end + + -- 5.2 style `loadfile` implemented in 5.1 + function M.loadfile(filename, mode, env) + if (mode or 'bt') ~= 'bt' then + local ioerr + local fh, err = io.open(filename, 'rb'); if not fh then return fh,err end + local function ld() + local chunk; chunk,ioerr = fh:read(4096); return chunk + end + local f, err = M.load(ld, filename and '@'..filename, mode, env) + fh:close() + if not f then return f, err end + if ioerr then return nil, ioerr end + return f + else + local f, err = loadfile(filename); if not f then return f, err end + if env then setfenv(f, env) end + return f + end + end +end + +if _G.setfenv then -- Lua 5.1 + M.setfenv = _G.setfenv + M.getfenv = _G.getfenv +else -- >= Lua 5.2 + -- helper function for `getfenv`/`setfenv` + local function envlookup(f) + local name, val + local up = 0 + local unknown + repeat + up=up+1; name, val = debug.getupvalue(f, up) + if name == '' then unknown = true end + until name == '_ENV' or name == nil + if name ~= '_ENV' then + up = nil + if unknown then + error("upvalues not readable in Lua 5.2 when debug info missing", 3) + end + end + return (name == '_ENV') and up, val, unknown + end + + -- helper function for `getfenv`/`setfenv` + local function envhelper(f, name) + if type(f) == 'number' then + if f < 0 then + error(("bad argument #1 to '%s' (level must be non-negative)") + :format(name), 3) + elseif f < 1 then + error("thread environments unsupported in Lua 5.2", 3) --[*] + end + f = debug.getinfo(f+2, 'f').func + elseif type(f) ~= 'function' then + error(("bad argument #1 to '%s' (number expected, got %s)") + :format(type(name, f)), 2) + end + return f + end + -- [*] might simulate with table keyed by coroutine.running() + + -- 5.1 style `setfenv` implemented in 5.2 + function M.setfenv(f, t) + local f = envhelper(f, 'setfenv') + local up, val, unknown = envlookup(f) + if up then + debug.upvaluejoin(f, up, function() return up end, 1) --unique upval[*] + debug.setupvalue(f, up, t) + else + local what = debug.getinfo(f, 'S').what + if what ~= 'Lua' and what ~= 'main' then -- not Lua func + error("'setfenv' cannot change environment of given object", 2) + end -- else ignore no _ENV upvalue (warning: incompatible with 5.1) + end + return f -- invariant: original f ~= 0 + end + -- [*] http://lua-users.org/lists/lua-l/2010-06/msg00313.html + + -- 5.1 style `getfenv` implemented in 5.2 + function M.getfenv(f) + if f == 0 or f == nil then return _G end -- simulated behavior + local f = envhelper(f, 'setfenv') + local up, val = envlookup(f) + if not up then return _G end -- simulated behavior [**] + return val + end + -- [**] possible reasons: no _ENV upvalue, C function +end + + +return M
--- a/lgen.lua Mon Sep 14 00:16:13 2009 +0300 +++ b/lgen.lua Sat Nov 01 23:34:21 2014 +0000 @@ -1,7 +1,12 @@ - + module('lgen', package.seeall) -- export src dst hierarchy +-- Lua 5.1 setfenv/getfenv compatibility for Lua 5.2 +local CE = require('compat_env') +_G.setfenv = CE.setfenv +_G.getfenv = CE.getfenv + require('scan') require('handlers') -- globally add missing stuff