Advertisement
Guest User

Class Module

a guest
Jul 2nd, 2012
6
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 2.54 KB | None | 0 0
  1. ---------
  2. --CLASS--
  3. ---------
  4. local class_list = {}
  5. local class_membercopy = function(v)
  6.     return type(v)=="table" and table.copy(v) or v
  7. end
  8. local class_extends = setmetatable({},{
  9.     __index = function(t,k) return{1, class_list[k] or error("base class not found: '"..tostring(k).."'")} end
  10. })
  11. local class_operator = function(op)
  12.     return function(f) return {2,{op,f}} end
  13. end
  14. local class_mt = {
  15.     __newindex = function(t,name,cls)
  16.         local constructor = cls[name] or function() end
  17.         local funcs,members = {},{}
  18.         local extends,meta = {},{__index = funcs}
  19.         local function fillextends(t)
  20.             if table.find(extends,t) then error("class '"..name.."' can only inherit '"..t.name.."' once") end
  21.             extends[#extends+1] = t
  22.             for i=1,#t[4] do
  23.                 fillextends(t[4][i])
  24.             end
  25.         end
  26.         if type(name)~="string" then error("class name must be a string") end
  27.         if type(constructor)~="function" then error("member with same name as class must be constructor function") end
  28.         for k,v in pairs(cls) do
  29.             if type(k) == "string" then
  30.                 local x = type(v) == "function" and funcs or members
  31.                 x[k] = class_membercopy(v)
  32.             elseif type(k) == "number" then
  33.                 assert(type(v)=="table","anonymous members are not allowed")
  34.                 if v[1] == 1 then
  35.                     fillextends(v[2])
  36.                 elseif v[1] == 2 then
  37.                     local op = v[2][1]
  38.                     local f = v[2][2]
  39.                     local t ={
  40.                         ["+"] = "__add", ["*"] = "__mult", ["-"] = "__sub", ["/"] = "__div", ["%"] = "__mod",
  41.                         ["^"] = "__pow", ["--"] = "__unm", [".."] = "__concat", ["#"] = "__len",
  42.                         ["()"] = "__call", ["~"] = "__gc"
  43.                     }
  44.                     meta[t[op] or op] = f
  45.                 end
  46.             end
  47.         end
  48.         for i=1,#extends do
  49.             for k,v in pairs(extends[i][3]) do members[k] = members[k] or v end
  50.         end
  51.         local constr = function(t, ...)
  52.             for i=1,#extends do extends[i][1](t) end
  53.             constructor(t,...)
  54.         end
  55.         class_list[name] = {constr,funcs,members,extends,meta,name=name}
  56.         funcs["type"] = function(t) return class_list[name] end
  57.         setmetatable(funcs,{
  58.             __index = function(t,k)
  59.                 for i=1,#extends do
  60.                     if extends[i][2][k] then    return extends[i][2][k] end
  61.                 end
  62.             end
  63.         })
  64.     end,
  65.     __index = function(t,name)
  66.         if name == "extends" then return class_extends
  67.         elseif name == "operator" then return class_operator end
  68.         local cls = class_list[name]
  69.         if not cls then
  70.             return function(x) t[name] = x end
  71.         end
  72.         local r = {}
  73.         for k,v in pairs(cls[3]) do
  74.             r[k] = class_membercopy(v)
  75.         end
  76.         return function(...)
  77.             setmetatable(r,cls[5])
  78.             cls[1](r,...)
  79.             return r
  80.         end
  81.     end
  82. }
  83. class = setmetatable({},class_mt)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement