PageRenderTime 49ms CodeModel.GetById 25ms RepoModel.GetById 1ms app.codeStats 0ms

/src/lua/package.lua

https://bitbucket.org/elcugo/t-engine
Lua | 222 lines | 164 code | 23 blank | 35 comment | 8 complexity | 112dabad6d32ad0127f4900ca7ac45f8 MD5 | raw file
Possible License(s): GPL-2.0
  1. -- tolua: package class
  2. -- Written by Waldemar Celes
  3. -- TeCGraf/PUC-Rio
  4. -- Jul 1998
  5. -- $Id$
  6. -- This code is free software; you can redistribute it and/or modify it.
  7. -- The software provided hereunder is on an "as is" basis, and
  8. -- the author has no obligation to provide maintenance, support, updates,
  9. -- enhancements, or modifications.
  10. -- Package class
  11. -- Represents the whole package being bound.
  12. -- The following fields are stored:
  13. -- {i} = list of objects in the package.
  14. classPackage = {
  15. _base = classContainer,
  16. type = 'package'
  17. }
  18. settag(classPackage,tolua_tag)
  19. -- Print method
  20. function classPackage:print ()
  21. print("Package: "..self.name)
  22. local i=1
  23. while self[i] do
  24. self[i]:print("","")
  25. i = i+1
  26. end
  27. end
  28. function classPackage:preprocess ()
  29. self.code = "\n"..self.code -- add a blank sentinel line
  30. -- avoid preprocessing verbatim lines
  31. local V = {}
  32. self.code = gsub(self.code,"\n(%s*%$[^%[%]][^\n]*)",function (v)
  33. tinsert(%V,v)
  34. return "\n$"..getn(%V).."$"
  35. end)
  36. -- avoid preprocessing embedded lua code
  37. local C = {}
  38. self.code = gsub(self.code,"\n%s*%$%[","\1") -- deal with embedded Lua code
  39. self.code = gsub(self.code,"\n%s*%$%]","\2")
  40. self.code = gsub(self.code,"(%b\1\2)", function (c)
  41. tinsert(%C,c)
  42. return "\n$["..getn(%C).."]$"
  43. end)
  44. -- perform global substitution
  45. self.code = gsub(self.code,"(//[^\n]*)","") -- eliminate C++ comments
  46. self.code = gsub(self.code,"/%*","\1")
  47. self.code = gsub(self.code,"%*/","\2")
  48. self.code = gsub(self.code,"%b\1\2","")
  49. self.code = gsub(self.code,"\1","/%*")
  50. self.code = gsub(self.code,"\2","%*/")
  51. self.code = gsub(self.code,"%s*@%s*","@") -- eliminate spaces beside @
  52. self.code = gsub(self.code,"%s?inline(%s)","%1") -- eliminate 'inline' keyword
  53. self.code = gsub(self.code,"%s?extern(%s)","%1") -- eliminate 'extern' keyword
  54. self.code = gsub(self.code,"%s?virtual(%s)","%1") -- eliminate 'virtual' keyword
  55. self.code = gsub(self.code,"public:","") -- eliminate 'public:' keyword
  56. self.code = gsub(self.code,"([^%w_])void%s*%*","%1_userdata ") -- substitute 'void*'
  57. self.code = gsub(self.code,"([^%w_])void%s*%*","%1_userdata ") -- substitute 'void*'
  58. self.code = gsub(self.code,"([^%w_])char%s*%*","%1_cstring ") -- substitute 'char*'
  59. -- restore embedded code
  60. self.code = gsub(self.code,"%$%[(%d+)%]%$",function (n)
  61. return %C[tonumber(n)]
  62. end)
  63. -- restore verbatim lines
  64. self.code = gsub(self.code,"%$(%d+)%$",function (n)
  65. return %V[tonumber(n)]
  66. end)
  67. end
  68. -- translate verbatim
  69. function classPackage:preamble ()
  70. output('/*\n')
  71. output('** Lua binding: '..self.name..'\n')
  72. output('** Generated automatically by '..TOLUA_VERSION..'\n')
  73. output('*/\n\n')
  74. output('#include "lua/tolua.h"\n\n')
  75. if not flags.h then
  76. output('/* Exported function */')
  77. output('int tolua_'..self.name..'_open (lua_State* tolua_S);')
  78. output('void tolua_'..self.name..'_close (lua_State* tolua_S);')
  79. output('\n')
  80. end
  81. local i=1
  82. while self[i] do
  83. self[i]:preamble()
  84. i = i+1
  85. end
  86. output('\n')
  87. output('/* function to register type */')
  88. output('static void toluaI_reg_types (lua_State* tolua_S)')
  89. output('{')
  90. foreach(_usertype,function(n,v) output(' tolua_usertype(tolua_S,"',v,'");') end)
  91. output('}')
  92. output('\n')
  93. output('/* error messages */')
  94. output('#define TOLUA_ERR_SELF tolua_error(tolua_S,\"invalid \'self\'\")')
  95. output('#define TOLUA_ERR_ASSIGN tolua_error(tolua_S,\"#vinvalid type in variable assignment.\")')
  96. output('\n')
  97. end
  98. -- register package
  99. -- write package open function
  100. function classPackage:register ()
  101. output("/* Open function */")
  102. output("int tolua_"..self.name.."_open (lua_State* tolua_S)")
  103. output("{")
  104. output(" tolua_open(tolua_S);")
  105. output(" toluaI_reg_types(tolua_S);")
  106. local i=1
  107. while self[i] do
  108. self[i]:register()
  109. i = i+1
  110. end
  111. output(" return 1;")
  112. output("}")
  113. end
  114. -- unregister package
  115. -- write package close function
  116. function classPackage:unregister ()
  117. output("/* Close function */")
  118. output("void tolua_"..self.name.."_close (lua_State* tolua_S)")
  119. output("{")
  120. local i=1
  121. while self[i] do
  122. self[i]:unregister()
  123. i = i+1
  124. end
  125. output("}")
  126. end
  127. -- write header file
  128. function classPackage:header ()
  129. output('/*\n') output('** Lua binding: '..self.name..'\n')
  130. output('** Generated automatically by '..TOLUA_VERSION..'.\n')
  131. output('*/\n\n')
  132. if not flags.h then
  133. output('/* Exported function */')
  134. output('int tolua_'..self.name..'_open (lua_State* tolua_S);')
  135. output('void tolua_'..self.name..'_close (lua_State* tolua_S);')
  136. output('\n')
  137. end
  138. end
  139. -- Internal constructor
  140. function _Package (t)
  141. t._base = classPackage
  142. settag(t,tolua_tag)
  143. return t
  144. end
  145. -- Constructor
  146. -- Expects the base file name.
  147. -- It assumes the file has extension ".pkg".
  148. function Package (name)
  149. -- read file
  150. local code = read("*a")
  151. code = "\n" .. code -- add sentinel
  152. -- deal with include directive
  153. local nsubst
  154. repeat
  155. code,nsubst = gsub(code,"\n%s*%$<(.-)>%s*\n",function (fn)
  156. local fp,msg = openfile(fn,'r')
  157. if not fp then
  158. error('#'..msg..': '..fn)
  159. end
  160. local s = read(fp,'*a')
  161. closefile(fp)
  162. return "\n" .. s
  163. end)
  164. until nsubst==0
  165. -- deal with include directive for C/C++ header files
  166. local nsubst
  167. repeat
  168. code,nsubst =
  169. gsub(code,"\n%s*%${(.-)}%s*\n",
  170. function (fn)
  171. local fp,msg = openfile(fn,'r')
  172. if not fp then
  173. error('#'..msg..': '..fn)
  174. end
  175. local s = read(fp,'*a')
  176. closefile(fp)
  177. -- extract marked code
  178. local T = {code="\n"}
  179. s= "\n" .. s .. "\n" -- add blank lines as sentinels
  180. -- extract one-line statments
  181. gsub(s,"\n(.-)[Tt][Oo][Ll][Uu][Aa]_[Ee][Xx][Pp][Oo][Rr][Tt][^\n]*\n",
  182. function (c) %T.code = %T.code .. c .. "\n" end
  183. )
  184. -- extract multiline statments
  185. gsub(s,"\n[^\n]*[Tt][Oo][Ll][Uu][Aa]_[Bb][Ee][Gg][Ii][Nn][^\n]*"..
  186. "(.-)" ..
  187. "\n[^\n]*[Tt][Oo][Ll][Uu][Aa]_[Ee][Nn][Dd][^\n]*\n",
  188. function (c) %T.code = %T.code .. c .. "\n" end
  189. )
  190. return T.code
  191. end)
  192. until nsubst==0
  193. local t = _Package(_Container{name=name, code=code})
  194. push(t)
  195. t:preprocess()
  196. t:parse(t.code)
  197. pop()
  198. return t
  199. end