summaryrefslogtreecommitdiff
path: root/src/lua/package.lua
diff options
context:
space:
mode:
Diffstat (limited to 'src/lua/package.lua')
-rw-r--r--src/lua/package.lua222
1 files changed, 222 insertions, 0 deletions
diff --git a/src/lua/package.lua b/src/lua/package.lua
new file mode 100644
index 00000000..42dbfaac
--- /dev/null
+++ b/src/lua/package.lua
@@ -0,0 +1,222 @@
+-- tolua: package class
+-- Written by Waldemar Celes
+-- TeCGraf/PUC-Rio
+-- Jul 1998
+-- $Id: package.lua,v 1.4 2002/01/03 13:45:08 takkaria Exp $
+
+-- This code is free software; you can redistribute it and/or modify it.
+-- The software provided hereunder is on an "as is" basis, and
+-- the author has no obligation to provide maintenance, support, updates,
+-- enhancements, or modifications.
+
+
+
+-- Package class
+-- Represents the whole package being bound.
+-- The following fields are stored:
+-- {i} = list of objects in the package.
+classPackage = {
+ _base = classContainer,
+ type = 'package'
+}
+settag(classPackage,tolua_tag)
+
+-- Print method
+function classPackage:print ()
+ print("Package: "..self.name)
+ local i=1
+ while self[i] do
+ self[i]:print("","")
+ i = i+1
+ end
+end
+
+function classPackage:preprocess ()
+ self.code = "\n"..self.code -- add a blank sentinel line
+ -- avoid preprocessing verbatim lines
+ local V = {}
+ self.code = gsub(self.code,"\n(%s*%$[^%[%]][^\n]*)",function (v)
+ tinsert(%V,v)
+ return "\n$"..getn(%V).."$"
+ end)
+ -- avoid preprocessing embedded lua code
+ local C = {}
+ self.code = gsub(self.code,"\n%s*%$%[","\1") -- deal with embedded Lua code
+ self.code = gsub(self.code,"\n%s*%$%]","\2")
+ self.code = gsub(self.code,"(%b\1\2)", function (c)
+ tinsert(%C,c)
+ return "\n$["..getn(%C).."]$"
+ end)
+ -- perform global substitution
+
+ self.code = gsub(self.code,"(//[^\n]*)","") -- eliminate C++ comments
+ self.code = gsub(self.code,"/%*","\1")
+ self.code = gsub(self.code,"%*/","\2")
+ self.code = gsub(self.code,"%b\1\2","")
+ self.code = gsub(self.code,"\1","/%*")
+ self.code = gsub(self.code,"\2","%*/")
+ self.code = gsub(self.code,"%s*@%s*","@") -- eliminate spaces beside @
+ self.code = gsub(self.code,"%s?inline(%s)","%1") -- eliminate 'inline' keyword
+ self.code = gsub(self.code,"%s?extern(%s)","%1") -- eliminate 'extern' keyword
+ self.code = gsub(self.code,"%s?virtual(%s)","%1") -- eliminate 'virtual' keyword
+ self.code = gsub(self.code,"public:","") -- eliminate 'public:' keyword
+ self.code = gsub(self.code,"([^%w_])void%s*%*","%1_userdata ") -- substitute 'void*'
+ self.code = gsub(self.code,"([^%w_])void%s*%*","%1_userdata ") -- substitute 'void*'
+ self.code = gsub(self.code,"([^%w_])char%s*%*","%1_cstring ") -- substitute 'char*'
+
+ -- restore embedded code
+ self.code = gsub(self.code,"%$%[(%d+)%]%$",function (n)
+ return %C[tonumber(n)]
+ end)
+ -- restore verbatim lines
+ self.code = gsub(self.code,"%$(%d+)%$",function (n)
+ return %V[tonumber(n)]
+ end)
+end
+
+-- translate verbatim
+function classPackage:preamble ()
+ output('/*\n')
+ output('** Lua binding: '..self.name..'\n')
+ output('** Generated automatically by '..TOLUA_VERSION..'\n')
+ output('*/\n\n')
+
+ output('#include "lua/tolua.h"\n\n')
+
+ if not flags.h then
+ output('/* Exported function */')
+ output('int tolua_'..self.name..'_open (lua_State* tolua_S);')
+ output('void tolua_'..self.name..'_close (lua_State* tolua_S);')
+ output('\n')
+ end
+
+ local i=1
+ while self[i] do
+ self[i]:preamble()
+ i = i+1
+ end
+ output('\n')
+ output('/* function to register type */')
+ output('static void toluaI_reg_types (lua_State* tolua_S)')
+ output('{')
+ foreach(_usertype,function(n,v) output(' tolua_usertype(tolua_S,"',v,'");') end)
+ output('}')
+ output('\n')
+
+ output('/* error messages */')
+ output('#define TOLUA_ERR_SELF tolua_error(tolua_S,\"invalid \'self\'\")')
+ output('#define TOLUA_ERR_ASSIGN tolua_error(tolua_S,\"#vinvalid type in variable assignment.\")')
+ output('\n')
+end
+
+-- register package
+-- write package open function
+function classPackage:register ()
+ output("/* Open function */")
+ output("int tolua_"..self.name.."_open (lua_State* tolua_S)")
+ output("{")
+ output(" tolua_open(tolua_S);")
+ output(" toluaI_reg_types(tolua_S);")
+ local i=1
+ while self[i] do
+ self[i]:register()
+ i = i+1
+ end
+ output(" return 1;")
+ output("}")
+end
+
+-- unregister package
+-- write package close function
+function classPackage:unregister ()
+ output("/* Close function */")
+ output("void tolua_"..self.name.."_close (lua_State* tolua_S)")
+ output("{")
+ local i=1
+ while self[i] do
+ self[i]:unregister()
+ i = i+1
+ end
+ output("}")
+end
+
+-- write header file
+function classPackage:header ()
+ output('/*\n') output('** Lua binding: '..self.name..'\n')
+ output('** Generated automatically by '..TOLUA_VERSION..'.\n')
+ output('*/\n\n')
+
+ if not flags.h then
+ output('/* Exported function */')
+ output('int tolua_'..self.name..'_open (lua_State* tolua_S);')
+ output('void tolua_'..self.name..'_close (lua_State* tolua_S);')
+ output('\n')
+ end
+end
+
+-- Internal constructor
+function _Package (t)
+ t._base = classPackage
+ settag(t,tolua_tag)
+ return t
+end
+
+-- Constructor
+-- Expects the base file name.
+-- It assumes the file has extension ".pkg".
+function Package (name)
+ -- read file
+ local code = read("*a")
+ code = "\n" .. code -- add sentinel
+ -- deal with include directive
+ local nsubst
+ repeat
+ code,nsubst = gsub(code,"\n%s*%$<(.-)>%s*\n",function (fn)
+ local fp,msg = openfile(fn,'r')
+ if not fp then
+ error('#'..msg..': '..fn)
+ end
+ local s = read(fp,'*a')
+ closefile(fp)
+ return "\n" .. s
+ end)
+ until nsubst==0
+
+ -- deal with include directive for C/C++ header files
+ local nsubst
+ repeat
+ code,nsubst =
+ gsub(code,"\n%s*%${(.-)}%s*\n",
+ function (fn)
+ local fp,msg = openfile(fn,'r')
+ if not fp then
+ error('#'..msg..': '..fn)
+ end
+ local s = read(fp,'*a')
+ closefile(fp)
+ -- extract marked code
+ local T = {code="\n"}
+ s= "\n" .. s .. "\n" -- add blank lines as sentinels
+ -- extract one-line statments
+ gsub(s,"\n(.-)[Tt][Oo][Ll][Uu][Aa]_[Ee][Xx][Pp][Oo][Rr][Tt][^\n]*\n",
+ function (c) %T.code = %T.code .. c .. "\n" end
+ )
+ -- extract multiline statments
+ gsub(s,"\n[^\n]*[Tt][Oo][Ll][Uu][Aa]_[Bb][Ee][Gg][Ii][Nn][^\n]*"..
+ "(.-)" ..
+ "\n[^\n]*[Tt][Oo][Ll][Uu][Aa]_[Ee][Nn][Dd][^\n]*\n",
+ function (c) %T.code = %T.code .. c .. "\n" end
+ )
+ return T.code
+ end)
+ until nsubst==0
+
+ local t = _Package(_Container{name=name, code=code})
+ push(t)
+ t:preprocess()
+ t:parse(t.code)
+ pop()
+ return t
+end
+
+