local Expression = {} local _expFunc = {} local _expEnvMT = {} local _expEnv = setmetatable({}, _expEnvMT) local pcall = pcall local setfenv = setfenv local _expContextStack = {} function Expression.Execute(expStr, expContext) local expFunc = _expFunc[expStr] if not expFunc then expFunc = loadstring(expStr) _expFunc[expStr] = expFunc end if expFunc then _expContextStack[#_expContextStack + 1] = _expEnvMT.__index _expEnvMT.__index = expContext setfenv(expFunc, _expEnv) -- simply just support 3 return values local suc, r1, r2, r3, r4 = pcall(expFunc) _expEnvMT.__index = _expContextStack[#_expContextStack] _expContextStack[#_expContextStack] = nil if suc then if r4 ~= nil then error('too many return values, should less than 3') else return r1, r2, r3 end else error(r1) end else error('load expression failed') end end function Expression.Release(expStr) if expStr then _expFunc[expStr] = nil else _expFunc = {} end end return Expression