autogen.monkey2 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451
  1. #Import "<std>"
  2. Using std..
  3. Class Parser
  4. Method New( text:String )
  5. _text=text
  6. Bump()
  7. End
  8. Property Text:String()
  9. Return _text
  10. End
  11. Property Toke:String()
  12. Return _toke
  13. End
  14. Property TokePos:Int()
  15. Return _tokePos
  16. End
  17. Method Bump:String()
  18. While PeekChr() And PeekChr()<=32
  19. ParseChr()
  20. End
  21. _tokePos=_pos
  22. Local chr:=ParseChr()
  23. If IsAlpha( chr ) Or chr=95
  24. While IsIdent( PeekChr() )
  25. ParseChr()
  26. Wend
  27. Else If chr=35 And (IsAlpha( PeekChr() ) Or PeekChr()=95 ) '#ident
  28. ParseChr()
  29. While IsIdent( PeekChr() )
  30. ParseChr()
  31. Wend
  32. Else If chr=48 And PeekChr()=120 '0x
  33. ParseChr()
  34. While IsHexDigit( PeekChr() )
  35. ParseChr()
  36. Wend
  37. Else If IsDigit( chr )
  38. While IsDigit( PeekChr() )
  39. ParseChr()
  40. Wend
  41. Endif
  42. _toke=_text.Slice( _tokePos,_pos )
  43. Return _toke
  44. End
  45. Method Error( err:String )
  46. Print "ERROR: "+err
  47. Print "Text: "+_text
  48. Print "Toke: "+Toke
  49. End
  50. Method Parse:String()
  51. Local toke:=Toke
  52. If Not toke Error( "Unexpected EOI" )
  53. Bump()
  54. Return toke
  55. End
  56. Method Parse( toke:String )
  57. If toke<>Toke Error( "Expecting:"+toke )
  58. Bump()
  59. End
  60. Method CParse:Bool( toke:String )
  61. If toke=Toke Bump() ; Return True
  62. Return False
  63. End
  64. Method ParseIdent:String()
  65. If Toke And IsIdent( Toke[0] )
  66. Local ident:=Toke
  67. Bump()
  68. Return ident
  69. End
  70. Error( "Expecting identifier" )
  71. Return ""
  72. End
  73. Method CParseIdent:String()
  74. If Toke And IsIdent( Toke[0] )
  75. Local ident:=Toke
  76. Bump()
  77. Return ident
  78. End
  79. Return ""
  80. End
  81. Method ParseType:String()
  82. Local isconst:=CParse( "const" )
  83. Local type:=Parse()
  84. If type="void" Or type="GLvoid" type="Void"
  85. If CParse( "*" )
  86. If isconst And (type="GLchar" Or type="GLubyte") type="CString" Else type+=" Ptr"
  87. Endif
  88. isconst=CParse( "const" )
  89. If CParse( "*" ) type+=" Ptr"
  90. If type="CString Ptr" type="GLcchar Ptr Ptr"
  91. Return type
  92. End
  93. Private
  94. Field _text:String
  95. Field _toke:String
  96. Field _pos:Int
  97. Field _tokePos:Int
  98. Method PeekChr:Int()
  99. Return _pos<_text.Length ? _text[_pos] Else 0
  100. End
  101. Method ParseChr:Int()
  102. Local chr:=PeekChr()
  103. If _pos<_text.Length _pos+=1
  104. Return chr
  105. End
  106. End
  107. Function FixIdent:String( ident:String )
  108. Select ident
  109. Case "ptr" Return "p"
  110. Case "string" Return "s"
  111. Case "array" Return "a"
  112. Case "end" Return "e"
  113. End
  114. Return ident
  115. End
  116. Class GLApi
  117. Field ident:String
  118. Field pfnident:String
  119. Field rtype:String
  120. Field crtype:String
  121. Field args:String
  122. Field cargs:String
  123. Method ParseRType( p:Parser )
  124. Local pos:=p.TokePos
  125. rtype=p.ParseType()
  126. crtype=p.Text.Slice( pos,p.TokePos ).Trim()
  127. End
  128. Method ParseArgs( p:Parser )
  129. args=""
  130. cargs=""
  131. p.Parse( "(" )
  132. If p.Toke<>")"
  133. Repeat
  134. Local pos:=p.TokePos
  135. Local argty:=p.ParseType()
  136. If argty="Void" Exit
  137. Local argid:=FixIdent( p.ParseIdent() )
  138. If p.CParse( "[" )
  139. While p.Toke And Not p.CParse( "]" )
  140. p.Bump()
  141. Wend
  142. Endif
  143. If args args+=","
  144. args+=argid+":"+argty
  145. If cargs cargs+=","
  146. cargs+=p.Text.Slice( pos,p.TokePos )
  147. If Not p.CParse( "," ) Exit
  148. Forever
  149. Endif
  150. p.Parse( ")" )
  151. End
  152. Method Mx2Decl:String()
  153. Return "Function "+ident+":"+rtype+"("+args+")" '=~qbb"+ident+"~q"
  154. End
  155. Method CDecl:String()
  156. Return "GLAPI "+crtype+" GLFUN("+ident+")("+cargs+");"
  157. End
  158. Method CDef:String()
  159. Return "#define "+ident+" bb"+ident
  160. End
  161. Method CInit:String()
  162. Return "bb"+ident+"=SDL_GL_GetProcAddress(~q"+ident+"~q);"
  163. End
  164. End
  165. Function Main()
  166. ChangeDir( "modules/opengl/autogen" )
  167. Local src:=LoadString( "gl_version_2_1.h" )
  168. src+="~n"+LoadString( "gl_extensions.h" )
  169. Assert( src )
  170. Local lines:=New StringStack
  171. Local defvals:=New StringMap<String>
  172. Local pfnapis:=New StringMap<GLApi>
  173. Local apis:=New Stack<GLApi>
  174. Local defs:=New Stack<String>
  175. For Local line:=Eachin src.Split( "~n" )
  176. line=line.Trim()
  177. If Not line Continue
  178. Local p:=New Parser( line )
  179. Select p.Toke
  180. Case "#define"
  181. p.Bump()
  182. Local ident:=p.ParseIdent()
  183. Local value:=p.Toke
  184. If defvals.Contains( ident )
  185. If defvals[ident]<>value Print "Error: #define error for: "+ident
  186. Continue
  187. Endif
  188. defvals[ident]=value
  189. If value="GLEW_GET_FUN"
  190. Local pfnident:="PFN"+ident.ToUpper()+"PROC"
  191. Local api:=pfnapis[pfnident]
  192. If Not api
  193. Print "Api for "+pfnident+" not found!"
  194. Continue
  195. Endif
  196. api.ident=ident
  197. apis.Add( api )
  198. Continue
  199. Endif
  200. If Not ident.StartsWith( "GL_" ) Continue
  201. defs.Add( ident )
  202. Case "typedef"
  203. p.Bump()
  204. 'typedef Void (GLAPIENTRY * PFNGLMULTITEXCOORD2DPROC) (GLenum target, GLdouble s, GLdouble t);
  205. Local api:=New GLApi
  206. api.ParseRType( p )
  207. If Not p.CParse( "(" ) Continue
  208. p.Parse( "GLAPIENTRY" )
  209. p.Parse( "*" )
  210. api.pfnident=p.ParseIdent()
  211. p.Parse( ")" )
  212. api.ParseArgs( p )
  213. p.Parse( ";" )
  214. pfnapis[api.pfnident]=api
  215. ' api.crtype+"!"+api.pfnident+" ("+api.cargs+");"
  216. Case "GLAPI"
  217. p.Bump()
  218. Local api:=New GLApi
  219. api.ParseRType( p )
  220. p.Parse( "GLAPIENTRY" )
  221. api.ident=p.ParseIdent()
  222. Local pfnident:="PFN"+api.ident.ToUpper()+"PROC"
  223. If pfnapis.Contains( pfnident )
  224. Print "Api for "+pfnident+" already found!"
  225. Continue
  226. Endif
  227. api.pfnident=pfnident
  228. api.ParseArgs( p )
  229. pfnapis[pfnident]=api
  230. apis.Add( api )
  231. End
  232. Next
  233. Local buf:=New StringStack,str:=""
  234. CreateDir( "../native" )
  235. '***** create bbopengl.h file *****
  236. '
  237. For Local def:=Eachin defs
  238. buf.Add( "#define "+def+" "+defvals[def] )
  239. Next
  240. Local hdefs:=buf.Join( "~n" )
  241. buf.Clear()
  242. For Local api:=Eachin apis
  243. buf.Add( api.CDecl() )
  244. Next
  245. Local cdecls:=buf.Join( "~n" )
  246. buf.Clear()
  247. For Local api:=Eachin apis
  248. buf.Add( api.CDef() )
  249. End
  250. Local cdefs:=buf.Join( "~n" )
  251. str=LoadString( "bbopengl_.h" )
  252. str=str.Replace( "${DEFS}",hdefs )
  253. str=str.Replace( "${DECLS}",cdecls )
  254. str=str.Replace( "${CDEFS}",cdefs )
  255. SaveString( str,"../native/bbopengl.h" )
  256. '***** create bbopengl.c file *****
  257. '
  258. buf.Clear()
  259. For Local api:=Eachin apis
  260. buf.Add( "~t"+api.CInit() )
  261. Next
  262. Local cinits:=buf.Join( "~n" )
  263. str=LoadString( "bbopengl_.c" )
  264. str=str.Replace( "${INITS}",cinits )
  265. SaveString( str,"../native/bbopengl.c" )
  266. '***** create opengl.monkey2 file *****
  267. '
  268. buf.Clear()
  269. For Local def:=Eachin defs
  270. buf.Add( "Const "+def+":Int" )
  271. Next
  272. Local mx2defs:=buf.Join( "~n" )
  273. buf.Clear()
  274. For Local api:=Eachin apis
  275. Local decl:=api.Mx2Decl()
  276. If Not decl Continue
  277. buf.Add( api.Mx2Decl() )
  278. Next
  279. Local mx2decls:=buf.Join( "~n" )
  280. str=LoadString( "bbopengl_.monkey2" )
  281. str=str.Replace( "${DEFS}",mx2defs )
  282. str=str.Replace( "${DECLS}",mx2decls )
  283. SaveString( str,"../native/bbopengl.monkey2" )
  284. End