| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248 |
- -- Copyright 2019 云风 https://github.com/cloudwu . All rights reserved.
- -- License (the same with bgfx) : https://github.com/bkaradzic/bgfx/blob/master/LICENSE
- local idl = {}
- local comments = {}
- function idl.comment(c)
- comments[#comments+1] = c
- end
- local all_types = {}
- local function copy_attribs(to, from)
- if type(from) == "table" then
- for k, v in pairs(from) do
- if type(k) == "number" then
- to[v] = true
- end
- to[k] = v
- end
- else
- to.value = from
- end
- end
- local function classdef(item, def)
- local function class(_, methodname)
- item.class = item.name
- item.name = methodname
- return def
- end
- return setmetatable({} , { __index = class, __call = function(_, value) return def(value) end })
- end
- local function new_type(typename)
- local t = { name = typename }
- if #comments > 0 then
- t.comments = comments
- comments = {}
- end
- all_types[#all_types+1] = t
- return t
- end
- local function typedef(_, typename)
- local t = new_type(typename)
- local function type_attrib(attrib)
- copy_attribs(t, attrib)
- end
- return function(cname)
- local typ = type(cname)
- if typ == "table" then
- type_attrib(cname)
- return
- end
- assert(typ == "string" , "type should be a string")
- t.cname = cname
- return type_attrib
- end
- end
- idl.typedef = setmetatable({} , { __index = typedef, __call = typedef })
- idl.types = all_types
- local function add_comment(item, comment)
- -- strip space
- comment = comment:match "(.-)%s*$"
- if item.comment then
- table.insert(item.comment, comment)
- else
- item.comment = { comment }
- end
- end
- local function enumdef(what)
- local function deffunc (_, typename)
- local t = new_type(typename)
- t[what] = {}
- local function enum_attrib(obj, attribs)
- copy_attribs(t, attribs)
- return obj
- end
- local function new_enum_item(_, itemname)
- local item = { name = itemname }
- t[what][#t[what] + 1] = item
- local function add_attrib_or_comment(obj , attribs)
- if type(attribs) == "string" then
- add_comment(item, attribs)
- elseif attribs then
- copy_attribs(item, attribs)
- end
- return obj
- end
- return setmetatable({}, { __index = new_enum_item, __call = add_attrib_or_comment })
- end
- return setmetatable({}, { __index = new_enum_item , __call = enum_attrib })
- end
- return setmetatable({} , { __index = deffunc , __call = deffunc })
- end
- idl.enum = enumdef "enum"
- idl.flag = enumdef "flag"
- local function structdef(_, typename)
- local t = new_type(typename)
- t.struct = {}
- local function struct_attrib(obj, attribs)
- copy_attribs(t, attribs)
- return obj
- end
- local function new_struct_item(_, itemname)
- local item = { name = itemname }
- t.struct[#t.struct + 1] = item
- local function item_attrib(obj, attribs)
- if type(attribs) == "string" then
- add_comment(item, attribs)
- else
- copy_attribs(item, attribs)
- end
- return obj
- end
- return function (itemtype)
- item.fulltype = itemtype
- return setmetatable({}, { __index = new_struct_item, __call = item_attrib })
- end
- end
- return setmetatable({}, { __index = new_struct_item , __call = struct_attrib })
- end
- idl.struct = setmetatable({}, { __index = structdef , __call = structdef })
- local function handledef(_, typename)
- local t = new_type(typename)
- t.handle = true
- return function (attribs)
- copy_attribs(t, attribs)
- return obj
- end
- end
- idl.handle = setmetatable({} , { __index = handledef, __call = handledef })
- local all_funcs = {}
- local function duplicate_arg_name(_, name)
- error ("Duplicate arg name " .. name)
- end
- local function attribs_setter(args, arg, args_desc)
- local attribs_setter
- local function arg_attrib_or_comment(_, attrib_or_comment )
- if type(attrib_or_comment) == "string" then
- add_comment(arg, attrib_or_comment)
- else
- copy_attribs(arg, attrib_or_comment)
- end
- return attribs_setter
- end
- -- next field (__index) or attrib/comment (__call)
- attribs_setter = setmetatable( {} , {
- __index = function(_, name)
- return args_desc(args, name)
- end
- , __call = arg_attrib_or_comment } )
- return attribs_setter
- end
- local function func(sets)
- return function (_, funcname)
- local f = { name = funcname , args = {} }
- if #comments > 0 then
- f.comments = comments
- comments = {}
- end
- sets[#sets+1] = f
- local args
- local function args_desc(_, args_name)
- args[args_name] = duplicate_arg_name
- return function (fulltype)
- local arg = {
- name = "_" .. args_name,
- fulltype = fulltype,
- }
- f.args[#f.args+1] = arg
- return attribs_setter(args, arg, args_desc)
- end
- end
- args = setmetatable({}, { __index = args_desc })
- local function rettype(value)
- assert(type(value) == "string", "Need return type")
- local ret = { fulltype = value }
- f.ret = ret
- return attribs_setter(args, ret, args_desc)
- end
- local function funcdef(value)
- if type(value) == "table" then
- copy_attribs(f, value)
- return rettype
- end
- return rettype(value)
- end
- return classdef(f, funcdef)
- end
- end
- idl.funcptr = setmetatable({}, { __index = func(all_types) })
- idl.func = setmetatable({}, { __index = func(all_funcs) })
- idl.funcs = all_funcs
- function idl.version(v)
- rawset(idl, "_version", v)
- end
- idl.vararg = "vararg"
- idl.out = "out"
- idl.inout = "inout"
- idl.const = "const"
- idl.ctor = "ctor"
- idl.cfunc = "cfunc"
- idl.underscore = "underscore"
- idl.conly = "conly"
- idl.cpponly = "cpponly"
- idl.cppinline = "cppinline"
- idl.shortname = "shortname"
- idl.NULL = "NULL"
- idl.UINT16_MAX = "UINT16_MAX"
- idl.INT32_MAX = "INT32_MAX"
- idl.UINT32_MAX = "UINT32_MAX"
- idl.UINT8_MAX = "UINT8_MAX"
- return setmetatable(idl , { __index = function (_, keyword)
- error (tostring(keyword) .. " is invalid")
- end})
|