From 80880761a7ddb78d6612363e98a61835c096b7c4 Mon Sep 17 00:00:00 2001 From: Manuel Simon Hirsig Date: Fri, 9 Sep 2016 23:01:32 +0200 Subject: [PATCH] backup --- libs/module.lua | 159 ++++++++++++++++++++++++++---------------------- 1 file changed, 86 insertions(+), 73 deletions(-) diff --git a/libs/module.lua b/libs/module.lua index 870cb91..cebf869 100644 --- a/libs/module.lua +++ b/libs/module.lua @@ -1,108 +1,121 @@ -if module then return end -local setfenv, setmetatable, unpack, _G = setfenv, setmetatable, unpack, getfenv(0) +if getmetatable(getfenv(0)) == false then return end +local setmetatable, setfenv, getglobal, _G = setmetatable, setfenv, getglobal, getfenv(0) local PRIVATE, FIELD, PUBLIC, ACCESSOR, MUTATOR = 0, 0, 1, 2, 4 local PUBLIC_FIELD, PUBLIC_ACCESSOR, PUBLIC_MUTATOR = PUBLIC+FIELD, PUBLIC+ACCESSOR, PUBLIC+MUTATOR +local READ, WRITE = 0, 1 +local OPERATION = { [FIELD]=READ, [ACCESSOR]=READ, [MUTATOR]=WRITE } local function error(msg, ...) return _G.error(format(msg or '', unpack(arg)) .. '\n' .. debugstack(), 0) end local function import_error() error('Import error.') end -local function declaration_error() error('Declaration error.') end +local function definition_error() error('Invalid definition.') end local function collision_error(key) error('"%s" already exists.', key) end local nop, id = function() end, function(v) return v end local interface_eq = function() return true end -local interface_mt, environment_mt, declarator_mt = { __metatable=false, __eq=interface_eq }, { __metatable=false }, { __metatable=false } local INTERFACE = setmetatable({}, { __eq=interface_eq }) -local __ = {} - -function interface_mt:__index(k) self=__[self] - return self[PUBLIC_FIELD][k] -end -function interface_mt:__newindex(k, v) self=__[self] - self[PUBLIC_MUTATOR][k](v) +local function proxy_mt(values, mutators, eq) + return { + __metatable = false, + __index = values, + __newindex = function(_, k, v) return mutators[k](v) end, + __eq = eq, + } end -function environment_mt:__index(k) self=__[self] - return self[FIELD][k] +local definition_helper_mt = { __metatable=false } +function definition_helper_mt:__index(k) + tinsert(self.definition_modifiers, k) + return self end -function environment_mt:__newindex(k, v) self=__[self] - local mutator = self[MUTATOR][k] - if mutator then - mutator(v) - elseif not self.defined[k] or collision_error(k) then - self.declarator[k] = v - end -end - do - local ACCESS, META = { public=PUBLIC, private=PRIVATE }, { get=ACCESSOR, set=MUTATOR } - function declarator_mt:__index(k) self=__[self] - if not self.declaration_access then - self.declaration_access = ACCESS[k] or declaration_error() - elseif not self.declaration_meta or declaration_error() then - self.declaration_meta = META[k] - self.declaration_modifiers[k] = true - end - return self.declarator - end - function declarator_mt:__newindex(k, v) self=__[self] - local access, meta = self.declaration_access, self.declaration_meta or FIELD + local TYPE = { get=ACCESSOR, set=MUTATOR } + function definition_helper_mt:__newindex(k, v) self=__[self] + if type(k) ~= 'string' or not strfind(k, '^[_%a][_%w]*') then definition_error() end if v ~= self.interface then - self.defined[k] = true - self[meta], self[access+meta] = v, v -- TODO performance assignment vs conditional + self.defined[OPERATION[type]..k] = self.defined[OPERATION[type]..k] and collision_error(k) or true + self[type], self[self.definition_access+type] = v, v elseif _G[k] ~= nil or error(nil) then _G[k] = v end - self.declaration_access, self.declaration_meta = nil, nil - end - function declarator_mt:__call() - self.default_access = (not self.declaration_meta or declaration_error()) and self.declaration_access + self.definition_access, self.definition_modifiers = nil, nil end end -local function import(self, interface) - local module = (interface == INTERFACE or import_error()) and __[interface] - for k, v in module[PUBLIC_FIELD] do - if not self.defined[k] then - self.defined[k], self[FIELD][k] = true, v - end - end - for k, v in module[PUBLIC_ACCESSOR] do - if not self.defined[k] then - self.defined[k], self[ACCESSOR][k] = true, v - end - end - for k, v in module[PUBLIC_MUTATOR] do - if not self.defined[k] then - self.defined[k], self[MUTATOR][k] = true, v +local import +do + local TYPES = {FIELD, ACCESSOR, MUTATOR} + function import(self, interface) + local module = (interface == INTERFACE or import_error()) and __[interface] + for _, type in TYPES do + for k, v in module[PUBLIC+type] do + if not self.defined[OPERATION[type]..k] then + self.defined[OPERATION[type]..k], self[type][k] = true, v + end + end end end end -local nop_mt = { __index=nop } -local mt = { __metatable=false } -function mt:__index(key) +local global_default_mt, nop_default_mt = { __index=getglobal }, { __index=nop } + +local global_mt = { __metatable=false } +function global_mt:__index(key) if key ~= 'module' then return end - local interface, environment, declarator = setmetatable({}, interface_mt), setmetatable({}, environment_mt), setmetatable({}, declarator_mt) - local accessors, public_accessors = setmetatable({}, { __index=_G }), {} + local definition_helper = setmetatable({}, definition_helper_mt) + local environment, interface = {}, {} + local accessors = setmetatable( + { + private = function() self.definition_access = PRIVATE; return definition_helper end, + public = function() self.definition_access = PUBLIC; return definition_helper end, + }, + global_default_mt + ) + local public_accessors = {} + local mutators = setmetatable({}, nop_default_mt) + local public_mutators = setmetatable({}, nop_default_mt) + local fields = setmetatable( + { + _G = _G, + _I = interface, + _E = environment, + import = function(interface) import(self, interface) end, + error = error, + nop = nop, + id = id, + }, + { __index=function(_, key) return accessors[key]() end } + ) + local public_fields = setmetatable( + {}, + { __index=function(_, key) return public_accessors[key]() end } + ) + setmetatable(environment, proxy_mt(fields, mutators)) + setmetatable(interface, proxy_mt(public_fields, public_mutators, interface_eq)) self = { - defined = { _G=true, _I=true, _E=true, public=true, private=true, import=true, _=true, error=true, nop=true, id=true }, - [FIELD] = setmetatable( - { _G=_G, _I=interface, _E=environment, import=function(interface) import(self, interface) end, error=error, nop=nop, id=id }, - {__index=function(_, key) return accessors[key]() end } - ), - [ACCESSOR] = setmetatable({ public=function() return declarator.public end, private=function() return declarator.private end }, nop_mt), - [MUTATOR] = setmetatable({}, nop_mt), - [PUBLIC_FIELD] = setmetatable({}, {__index=function(_, key) return public_accessors[key]() end}), - [PUBLIC_ACCESSOR] = setmetatable({}, nop_mt), - [PUBLIC_MUTATOR] = setmetatable({}, nop_mt), + defined = { + [FIELD..'_G'] = true, + [FIELD..'_I'] = true, + [FIELD..'_E'] = true, + [FIELD..'import'] = true, + [FIELD..'_'] = true, + [FIELD..'error'] =true, + [FIELD..'nop'] = true, + [FIELD..'id'] = true, + [ACCESSOR..'public'] = true, + [ACCESSOR..'private'] = true, + }, + [FIELD] = fields, + [PUBLIC_FIELD] = public_fields, + [ACCESSOR] = accessors, + [PUBLIC_ACCESSOR] = public_accessors, + [MUTATOR] = mutators, + [PUBLIC_MUTATOR] = public_mutators, interface = interface, - declarator = declarator, } - __[interface], __[environment], __[declarator] = self, self, self setfenv(2, environment) return interface end -setmetatable(_G, mt) \ No newline at end of file +setmetatable(_G, global_mt) \ No newline at end of file