iparser.bmx 45 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018
  1. ' Copyright (c) 2013-2024 Bruce A Henderson
  2. '
  3. ' Based on the public domain Monkey "trans" by Mark Sibly
  4. '
  5. ' This software is provided 'as-is', without any express or implied
  6. ' warranty. In no event will the authors be held liable for any damages
  7. ' arising from the use of this software.
  8. '
  9. ' Permission is granted to anyone to use this software for any purpose,
  10. ' including commercial applications, and to alter it and redistribute it
  11. ' freely, subject to the following restrictions:
  12. '
  13. ' 1. The origin of this software must not be misrepresented; you must not
  14. ' claim that you wrote the original software. If you use this software
  15. ' in a product, an acknowledgment in the product documentation would be
  16. ' appreciated but is not required.
  17. '
  18. ' 2. Altered source versions must be plainly marked as such, and must not be
  19. ' misrepresented as being the original software.
  20. '
  21. ' 3. This notice may not be removed or altered from any source
  22. ' distribution.
  23. '
  24. 'SuperStrict
  25. 'Import BRL.MaxUtil
  26. 'Import "parser_factory.bmx"
  27. Const DECL_GLOBAL:Int = $10
  28. Const DECL_FIELD:Int = $20
  29. Const DECL_CONST:Int = $40
  30. Const DECL_LOCAL:Int = $80
  31. Type TIParser
  32. Field _toker:TToker
  33. Field _toke$
  34. Field _tokeType:Int
  35. Field _tokeSpace:Int
  36. Field _tokerStack:TList=New TList'<TToker>
  37. Method ParseModuleImport:Int(pmod:TModuleDecl, modpath:String, path:String, imp:String = Null, iData:String = Null, attrs:Long = 0, relPath:String = "", isFileImport:Int = 0)
  38. Const STATE_CLASS:Int = 1
  39. If Not modpath Then
  40. modpath = imp
  41. End If
  42. ' already imported??
  43. If _appInstance.IsImported(modpath)
  44. ' add import to the scope (so we can find decls in it later)
  45. ' but don't add it if pmod is the apps' main module
  46. If _appInstance.mainModule <> pmod Then
  47. pmod.AddImport(modpath, _appInstance.globalImports.ValueForKey(modpath))
  48. End If
  49. Return False
  50. Else If imp Then
  51. ' if "imp" is set, this is a file import. We need to check for it too, or we may end up importing it twice.
  52. If _appInstance.IsImported(imp)
  53. ' add import to the scope (so we can find decls in it later)
  54. ' but don't add it if pmod is the apps' main module
  55. If _appInstance.mainModule <> pmod Then
  56. pmod.AddImport(imp, _appInstance.globalImports.ValueForKey(imp))
  57. End If
  58. Return False
  59. End If
  60. End If
  61. Local prefix:String
  62. If isFileImport And opt_buildtype = BUILDTYPE_APP Then
  63. prefix = "m_"
  64. End If
  65. Local _mod:TModuleDecl = New TModuleDecl.Create(prefix + modpath, "bb" + modpath, path, attrs)
  66. Select modpath
  67. Case "brl.classes", "brl.blitzkeywords"
  68. _mod.UpdateFilePath(_mod.filepath + "." + modpath)
  69. End Select
  70. _mod.declImported = True
  71. _mod.relpath = relPath
  72. _mod.pmod = pmod
  73. If modpath = "brl.blitz" Then
  74. If pmod.imported.Contains(modpath) Then
  75. _mod = TModuleDecl(pmod.imported.ValueForKey(modpath))
  76. Else
  77. pmod.AddImport(modpath, _mod)
  78. End If
  79. ' import Object and String definitions
  80. Local par:TIParser = New TIParser
  81. If FileType(modulepath("brl.blitz") + "\blitz_classes." + opt_platform + ".i") Then
  82. par.ParseModuleImport(_mod, "brl.classes", modulepath("brl.blitz"), modulepath("brl.blitz") + "\blitz_classes." + opt_platform + ".i")
  83. Else
  84. par.ParseModuleImport(_mod, "brl.classes", modulepath("brl.blitz"), modulepath("brl.blitz") + "\blitz_classes.i")
  85. End If
  86. ' set up built-in keywords
  87. par = New TIParser
  88. par.ParseModuleImport(_mod, "brl.blitzkeywords", "", "", MakeKeywords())
  89. Else
  90. pmod.AddImport(modpath, _mod)
  91. End If
  92. _appInstance.globalImports.Insert(modpath, _mod)
  93. Local ipath:String
  94. 'Local ipath:String = path + "\" + ModuleIdent(modpath) + ".release.macos.x86.i"
  95. If imp Then
  96. ipath = imp
  97. ' add to imports
  98. pmod.AddImport(ipath, _mod)
  99. _appInstance.globalImports.Insert(ipath, _mod)
  100. Else
  101. ipath = path + "/" + ModuleIdent(modpath) + FileMung() + ".i"
  102. End If
  103. If Not iData Then
  104. If Not FileType(ipath) Then
  105. Err "Can't find interface for module '" + modpath + "'"
  106. Return False
  107. End If
  108. 'Local ifile:String[] = LoadString(ipath).Split("~n")
  109. _toker = New TToker.Create( ipath,LoadString( ipath ) )
  110. Else
  111. _toker = New TToker.Create( ipath, iData)
  112. End If
  113. Local toker:TToker = _toker
  114. Repeat
  115. Local pos:Int
  116. pos = toker._tokePos
  117. toker.NextToke
  118. Local line:Int
  119. Local state:Int
  120. Local class:TClassDecl
  121. Local stm:String
  122. Select toker.Toke().ToLower()
  123. Case "superstrict"
  124. _mod.attrs :| MODULE_SUPERSTRICT
  125. Continue
  126. Case "import"
  127. toker.NextToke()
  128. If toker.TokeType()=TOKE_SPACE toker.NextToke()
  129. ' skip non-module imports
  130. If toker.TokeType()=TOKE_STRINGLIT
  131. Local iRelPath:String = ParseStringLit()
  132. SetErr
  133. If iRelPath.EndsWith(".bmx") Then
  134. Local origPath:String = RealPath(ExtractDir(path) + "/" + iRelPath)
  135. Local iPath:String = OutputFilePath(origPath, FileMung(), "i")
  136. If FileType( iPath )<>FILETYPE_FILE
  137. Err "File '"+ iPath +"' not found."
  138. EndIf
  139. If _mod.imported.Contains( iPath ) Continue
  140. Local modpath:String
  141. If opt_buildtype = BUILDTYPE_MODULE Then
  142. Local dir:String = ExtractDir(origPath).ToLower()
  143. dir = dir[dir.findLast("/") + 1..]
  144. If dir.EndsWith(".mod") Then
  145. dir = ""
  146. Else
  147. dir :+ "_"
  148. End If
  149. Local file:String = StripDir(origPath).ToLower()
  150. modpath = opt_modulename + "_" + dir + StripExt(file)
  151. 'sanitize the path, remove non-allowed chars
  152. modpath = TStringHelper.Sanitize(modpath.ToLower())
  153. Else
  154. ' todo file imports for apps
  155. 'internalErr
  156. End If
  157. ' Local mdecl:TDecl=TDecl(pmod.GetDecl( modpath ))
  158. ' If Not mdecl
  159. New TIParser.ParseModuleImport( _mod, modpath, origPath, iPath, , , iRelPath)
  160. ' Else
  161. ' _mod.imported.Insert(modpath, mdecl)
  162. ' EndIf
  163. Else
  164. If iRelPath.StartsWith("-") Then
  165. If Not _mod.fileImports.Contains(iRelPath) Then
  166. _mod.fileImports.AddLast(iRelPath)
  167. End If
  168. End If
  169. End If
  170. Else
  171. Local m:String = toker._toke
  172. toker.NextToke()
  173. Parse(".")
  174. m :+ "." + toker._toke
  175. SetErr
  176. Local mdecl:TDecl=TDecl(pmod.GetDecl( m ))
  177. If Not mdecl
  178. Local path:String = modulepath(m)
  179. ' parse the imported module
  180. New TIParser.ParseModuleImport( _mod, m, path )
  181. Else
  182. _mod.AddImport(m, mdecl)
  183. EndIf
  184. End If
  185. Continue
  186. Case "moduleinfo"
  187. toker.nextToke()
  188. If toker.TokeType()=TOKE_SPACE toker.NextToke()
  189. Continue
  190. case "#"
  191. toker.nextToke()
  192. Parse("pragma")
  193. toker.nextToke()
  194. Continue
  195. Case "~r", "~n"
  196. Continue
  197. Default
  198. stm = toker.Toke()
  199. Local v:String = toker.NextToke()
  200. Select v
  201. Case "^"
  202. toker.rollback(pos)
  203. toker.NextToke()
  204. ' class decl
  205. class = ParseClassDecl( stm,0 )
  206. class.declImported = True
  207. Local parsed:Int
  208. For Local i:Int = 0 Until _toke.Length
  209. Select _toke[i]
  210. Case Asc("F")
  211. class.attrs :| DECL_FINAL
  212. parsed = True
  213. Case Asc("A")
  214. class.attrs :| DECL_ABSTRACT
  215. 'ApplyFunctionAttributes(class, DECL_ABSTRACT)
  216. parsed = True
  217. Case Asc("S")
  218. class.attrs :| CLASS_STRUCT
  219. parsed = True
  220. Case Asc("E")
  221. class.attrs :| DECL_EXTERN
  222. ApplyFunctionAttributes(class, DECL_EXTERN)
  223. parsed = True
  224. Case Asc("W")
  225. If opt_platform = "win32" Then
  226. class.attrs :| DECL_API_STDCALL
  227. ApplyFunctionAttributes(class, DECL_API_STDCALL)
  228. End If
  229. parsed = True
  230. Case Asc("I")
  231. class.attrs :| CLASS_INTERFACE
  232. ApplyFunctionAttributes(class, DECL_ABSTRACT)
  233. parsed = True
  234. Case Asc("G")
  235. class.attrs :| CLASS_GENERIC
  236. parsed = True
  237. Case Asc("P")
  238. class.attrs :| DECL_PRIVATE
  239. parsed = True
  240. End Select
  241. Next
  242. If parsed Then
  243. NextToke
  244. End If
  245. If CParse( "=" )
  246. If Not class.IsExtern() Then
  247. class.munged=ParseStringLit()
  248. If class.ident <> "String" Then
  249. For Local fdecl:TFieldDecl = EachIn class._decls
  250. fdecl.munged = "_" + class.munged + "_" + fdecl.ident
  251. fdecl.munged = fdecl.munged.ToLower()
  252. Next
  253. End If
  254. ' process generic details
  255. If class.attrs & CLASS_GENERIC Then
  256. If _toke <> "," Then
  257. Err "Syntax error - unexpected token '" + _toke + "'"
  258. End If
  259. NextToke
  260. Parse "<"
  261. Local args:TType[]
  262. Local nargs:Int
  263. Repeat
  264. Local arg:TType = ParseType()
  265. If args.Length=nargs args=args+ New TType[10]
  266. args[nargs]=arg
  267. nargs:+1
  268. Until Not CParse(",")
  269. args=args[..nargs]
  270. Parse ">"
  271. Parse "{"
  272. ' line no
  273. If _tokeType <> TOKE_INTLIT Then
  274. Err "Syntax error - unexpected token '" + _toke + "'"
  275. End If
  276. Local line:Int = _toke.ToInt()
  277. NextToke
  278. Parse ","
  279. ' source size
  280. If _tokeType <> TOKE_INTLIT Then
  281. Err "Syntax error - unexpected token '" + _toke + "'"
  282. End If
  283. Local size:Int = _toke.ToInt()
  284. NextToke
  285. Parse ","
  286. ' path
  287. If _tokeType <> TOKE_STRINGLIT Then
  288. Err "Syntax error - unexpected token '" + _toke + "'"
  289. End If
  290. Local path:String = BmxUnquote(_toke)
  291. NextToke
  292. Parse ","
  293. ' source
  294. If _tokeType <> TOKE_STRINGLIT Then
  295. Err "Syntax error - unexpected token '" + _toke + "'"
  296. End If
  297. Local source:String = BmxUnquote(_toke)
  298. NextToke
  299. Parse "}"
  300. class.templateSource = TTemplateRecord.Load(line, path, size, source)
  301. Local toker:TToker = New TToker.Create(path, class.templateSource.source, False, line)
  302. Local parser:TParser = New TParser.Create( toker, _appInstance )
  303. Local m:TModuleDecl = New TModuleDecl
  304. parser._module = m
  305. Local cdecl:TClassDecl = Null
  306. Select parser._toke
  307. Case "type"
  308. cdecl = parser.ParseClassDecl(parser._toke,0)
  309. Case "interface"
  310. cdecl = parser.ParseClassDecl(parser._toke, CLASS_INTERFACE|DECL_ABSTRACT )
  311. End Select
  312. Local ty:TType = args[0]
  313. Local genDecl:TClassDecl = TClassDecl(_mod.GetDecl(cdecl.IdentLower()))
  314. If Not genDecl Then
  315. genDecl = TClassDecl(pmod.GetDecl(cdecl.identLower()))
  316. End If
  317. If genDecl Then
  318. If Not TIdentType(ty) Or (TIdentType(ty) And TIdentType(ty).ident <> "?") Then
  319. cdecl = genDecl.GenClassInstance(args, True)
  320. Local scopeMunged:String = class.munged
  321. If class.munged.Find("|") >= 0 Then
  322. Local mung:String[] = class.munged.Split("|")
  323. scopeMunged = mung[0]
  324. cdecl.munged = mung[1]
  325. End If
  326. cdecl.scope.munged = scopeMunged
  327. cdecl.scope.scope = _appInstance
  328. End If
  329. ' don't add to module
  330. class = Null
  331. Else
  332. class = cdecl
  333. class.declImported = True
  334. If Not TIdentType(ty) Or (TIdentType(ty) And TIdentType(ty).ident <> "?") Then
  335. cdecl = class.GenClassInstance(args)
  336. cdecl.declImported = True
  337. _mod.munged = class.munged
  338. End If
  339. End If
  340. End If
  341. Else
  342. Parse "0"
  343. If Not class.munged Then
  344. class.munged = class.ident
  345. End If
  346. End If
  347. EndIf
  348. If class Then
  349. _mod.InsertDecl(class)
  350. End If
  351. 'state = STATE_CLASS
  352. 'Exit
  353. Case "\"
  354. toker.rollback(pos)
  355. toker.NextToke()
  356. Local enumDecl:TEnumDecl = ParseEnumDecl( stm )
  357. enumDecl.declImported = True
  358. If CParse("F") Then
  359. enumDecl.isFlags = True
  360. End If
  361. Parse("=")
  362. If _tokeType <> TOKE_STRINGLIT Then
  363. Err "Syntax error - unexpected token '" + _toke + "'"
  364. End If
  365. enumDecl.munged = BmxUnquote(_toke)
  366. _mod.InsertDecl(enumDecl)
  367. Default
  368. If toker._tokeType = TOKE_EOF
  369. Exit
  370. End If
  371. Local a:Long
  372. Local ty:TType = ParseDeclType(a)
  373. If CParse("(") Then
  374. toker.rollback(pos)
  375. toker.NextToke()
  376. Local decl:TFuncDecl = ParseFuncDecl( _toke, 0 )
  377. decl.declImported = True
  378. ' an array of function pointers?
  379. If CParse( "&" ) Then
  380. End If
  381. If IstStaticArrayDef() Then
  382. attrs :| DECL_STATIC
  383. End If
  384. While IsArrayDef()
  385. ty = ParseArrayType(ty)
  386. If CParse( "&" ) Then
  387. End If
  388. Wend
  389. If decl.attrs & FUNC_PTR Then
  390. Local fpty:TType = New TFunctionPtrType
  391. TFunctionPtrType(fpty).func = decl
  392. If TArrayType(ty) Then
  393. TArrayType(ty).elemType = fpty
  394. Else
  395. ty = fpty
  396. End If
  397. 'Local declInit:TExpr = decl.declInit
  398. 'decl.declInit = Null
  399. Local gdecl:TGlobalDecl = New TGlobalDecl.Create( decl.ident,ty, Null, DECL_GLOBAL )
  400. gdecl.munged = decl.munged
  401. _mod.InsertDecl gdecl
  402. gdecl.declImported = True
  403. If CParse( "=" )
  404. If CParse("mem")
  405. If CParse(":")
  406. If CParse("p")
  407. If CParse("(") Then
  408. gdecl.munged = ParseStringLit()
  409. ' for function pointers, ensure actual function reference is set too.
  410. 'If TFunctionPtrType(gdecl.declTy) Then
  411. ' TFunctionPtrType(gdecl.declTy).func.munged = gdecl.munged
  412. 'Else If TArrayType(gdecl.declTy) Then
  413. '
  414. 'End If
  415. TFunctionPtrType(fpty).func.munged = gdecl.munged
  416. Parse(")")
  417. EndIf
  418. End If
  419. Else
  420. If CParse("(") Then
  421. gdecl.munged = ParseStringLit()
  422. Parse(")")
  423. EndIf
  424. End If
  425. Else
  426. If TStringType(ty)
  427. If CParse("$") Then
  428. gdecl.declInit = ParseUnaryExpr()
  429. End If
  430. Else
  431. ' a default value ?
  432. gdecl.declInit = ParseUnaryExpr()
  433. End If
  434. End If
  435. End If
  436. Else
  437. _mod.InsertDecl decl
  438. End If
  439. Else
  440. toker.rollback(pos)
  441. toker.NextToke()
  442. Local decl:TDecl = ParseDecl( _toke, DECL_CONST | DECL_EXTERN)'DECL_GLOBAL | DECL_EXTERN )
  443. _mod.InsertDecl decl
  444. decl.declImported = True
  445. End If
  446. End Select
  447. End Select
  448. line :+ 1
  449. Forever
  450. ' semant imported classes
  451. For Local cdecl:TClassDecl = EachIn _mod.Decls()
  452. cdecl.Semant()
  453. If Not cdecl.args Then
  454. cdecl.FinalizeClass()
  455. End If
  456. Next
  457. Return True
  458. End Method
  459. Method ParseUnaryExpr:TExpr()
  460. SkipEols
  461. Local op$=_toke
  462. Select op
  463. Case "+","-","~~","not"
  464. NextToke
  465. Local expr:TExpr=ParseUnaryExpr()
  466. Return New TUnaryExpr.Create( op,expr )
  467. End Select
  468. Return ParsePrimaryExpr( False )
  469. End Method
  470. Method ParsePrimaryExpr:TExpr( stmt:Int )
  471. Local expr:TExpr
  472. Select _tokeType
  473. 'Case TOKE_IDENT
  474. ' expr=New TIdentExpr.Create( ParseIdent() )
  475. Case TOKE_INTLIT
  476. expr=New TConstExpr.Create( New TIntType,_toke )
  477. NextToke
  478. Case TOKE_LONGLIT
  479. expr=New TConstExpr.Create( New TLongType,_toke )
  480. NextToke
  481. Case TOKE_FLOATLIT
  482. Local value:String = _toke
  483. NextToke
  484. If CParse("!") Then
  485. expr=New TConstExpr.Create( New TDoubleType,value )
  486. Else
  487. CParse("#")
  488. expr=New TConstExpr.Create( New TFloatType,value )
  489. End If
  490. Case TOKE_STRINGLIT
  491. expr=New TConstExpr.Create( New TStringType,BmxUnquote( _toke ) )
  492. NextToke
  493. Case TOKE_IDENT
  494. If _toke = "nan" Or _toke = "inf" Then
  495. Local value:String
  496. Select _toke
  497. Case "inf"
  498. value = "1.#INF0000"
  499. Case "nan"
  500. value = "-1.#IND0000"
  501. End Select
  502. NextToke
  503. If CParse("!") Then
  504. value :+ "00000000"
  505. expr=New TConstExpr.Create( New TDoubleType,value )
  506. Else
  507. CParse("#")
  508. expr=New TConstExpr.Create( New TFloatType,value )
  509. End If
  510. Else
  511. Err "Syntax error - unexpected token '"+_toke+"'"
  512. End If
  513. Default
  514. Err "Syntax error - unexpected token '"+_toke+"'"
  515. End Select
  516. Return expr
  517. End Method
  518. Method ParseClassDecl:TClassDecl( toke$,attrs:Long )
  519. SetErr
  520. 'If toke Parse toke
  521. Local id$=ParseIdent()
  522. Local args:TTemplateArg[]
  523. Local superTy:TIdentType
  524. Local imps:TIdentType[]
  525. If CParse( "^" )
  526. If CParse( "null" )
  527. superTy=Null
  528. Else
  529. superTy=ParseIdentType()
  530. 'If superTy.ident <> "Object" Then
  531. ' superTy = TIdentType(superTy.Semant())
  532. 'EndIf
  533. EndIf
  534. Else
  535. superTy = New TIdentType.Create( "brl.classes.object" )
  536. EndIf
  537. ' implements
  538. If CParse("@") Then
  539. Local nimps:Int
  540. Repeat
  541. If imps.Length=nimps imps=imps + New TIdentType[10]
  542. imps[nimps]=ParseIdentType()
  543. nimps:+1
  544. Until Not CParse(",")
  545. imps=imps[..nimps]
  546. End If
  547. Local classDecl:TClassDecl=New TClassDecl.Create( id,args,superTy,imps,attrs )
  548. If classDecl.IsExtern()
  549. classDecl.munged=classDecl.ident
  550. If CParse( "=" ) classDecl.munged=ParseStringLit()
  551. EndIf
  552. 'If classDecl.IsTemplateArg() Return classDecl
  553. Local decl_attrs:Long=(attrs & DECL_EXTERN)
  554. Local method_attrs:Long=decl_attrs
  555. If attrs & CLASS_INTERFACE method_attrs:|DECL_ABSTRACT
  556. Repeat
  557. SkipEols
  558. 'If IsSpace(Asc(_toker._toke))
  559. ' _toker.NextToke
  560. 'End If
  561. Select _toker._toke
  562. Case "{"
  563. '_toker.
  564. NextToke
  565. Case "}"
  566. '_toker.
  567. NextToke
  568. Exit
  569. Case "-" ' method
  570. 'DebugStop
  571. '_toker.
  572. NextToke
  573. Local decl:TFuncDecl = ParseFuncDecl( _toke,method_attrs|FUNC_METHOD, ,classDecl )
  574. decl.declImported = True
  575. 'If decl.IsCtor() decl.retTypeExpr=New TObjectType.Create( classDecl )
  576. classDecl.InsertDecl decl
  577. Case "+" ' function
  578. NextToke
  579. Local decl:TFuncDecl = ParseFuncDecl( _toke,method_attrs )
  580. decl.declImported = True
  581. 'If decl.IsCtor() decl.retTypeExpr=New TObjectType.Create( classDecl )
  582. classDecl.InsertDecl decl
  583. Case ".", "@", "~~" ' field
  584. Local d_attrs:Long = decl_attrs | DECL_FIELD
  585. If _toker._toke = "." Then
  586. NextToke
  587. Else
  588. While _toker._toke = "@" Or _toker._toke = "~~"
  589. If _toker._toke = "@" Then
  590. d_attrs :| DECL_READ_ONLY
  591. End If
  592. If _toker._toke = "~~" Then
  593. d_attrs :| DECL_STATIC
  594. End If
  595. NextToke
  596. Wend
  597. End If
  598. Local decl:TDecl= ParseDecl( _toke,d_attrs )
  599. classDecl.InsertDecl decl
  600. Rem
  601. Case "private"
  602. NextToke
  603. decl_attrs=decl_attrs | DECL_PRIVATE
  604. Case "public"
  605. NextToke
  606. decl_attrs=decl_attrs & ~DECL_PRIVATE
  607. Case "const","global","field"
  608. If (attrs & CLASS_INTERFACE) And _toke<>"const"
  609. Err "Interfaces can only contain constants and methods."
  610. EndIf
  611. classDecl.InsertDecls ParseDecls( _toke,decl_attrs )
  612. Case "method"
  613. Local decl:TFuncDecl=ParseFuncDecl( _toke,method_attrs )
  614. If decl.IsCtor() decl.retTypeExpr=New TObjectType.Create( classDecl )
  615. classDecl.InsertDecl decl
  616. Case "function"
  617. If (attrs & CLASS_INTERFACE) And _toke<>"const"
  618. Err "Interfaces can only contain constants and methods."
  619. EndIf
  620. Local decl:TFuncDecl=ParseFuncDecl( _toke,decl_attrs )
  621. classDecl.InsertDecl decl
  622. End Rem
  623. 'Default
  624. ' Err "Syntax error - expecting class member declaration."
  625. End Select
  626. If _toker._tokeType = TOKE_IDENT Then
  627. ' Const / Global?
  628. 'NextToke
  629. 'decl_attrs :| DECL_CONST
  630. Local decl:TDecl= ParseDecl( _toke,decl_attrs | DECL_CONST)
  631. classDecl.InsertDecl decl
  632. decl.declImported = True
  633. End If
  634. Forever
  635. If toke CParse toke
  636. Return classDecl
  637. End Method
  638. Method ParseEnumDecl:TEnumDecl( toke$ )
  639. SetErr
  640. Local id$=ParseIdent()
  641. Local ty:TType
  642. Local attrs:Long
  643. Parse( "\" )
  644. ty=ParseDeclType(attrs, False)
  645. Local enumDecl:TEnumDecl=New TEnumDecl.Create( id, ty, False, Null )
  646. Local index:Int
  647. Repeat
  648. SkipEols
  649. Select _toker._toke
  650. Case "{"
  651. NextToke
  652. Case "}"
  653. NextToke
  654. Exit
  655. Default
  656. Local decl:TEnumValueDecl = ParseEnumValueDecl(_toke, index, ty)
  657. enumDecl.InsertDecl decl
  658. enumDecl.values :+ [decl]
  659. index :+ 1
  660. End Select
  661. Forever
  662. Return enumDecl
  663. End Method
  664. Method ParseEnumValueDecl:TEnumValueDecl(toke:String, index:Int, enumTy:TType)
  665. Local id:String = ParseIdent()
  666. Parse("=")
  667. Local op:String
  668. If _toke = "-" Then
  669. op = "-"
  670. NextToke
  671. End If
  672. Local expr:TExpr = New TConstExpr.Create( enumTy.Copy(), op + _toke )
  673. Local valDecl:TEnumValueDecl = New TEnumValueDecl.Create(id, index, expr)
  674. NextToke
  675. Return valDecl
  676. End Method
  677. Method Parse( toke$ )
  678. If Not CParse( toke )
  679. Err "Syntax error - expecting '"+toke+"'."
  680. EndIf
  681. End Method
  682. Method ParseIdent$()
  683. Select _toker._toke.tolower()
  684. Case "@" _toker.NextToke
  685. Case "string","___array","object"
  686. Case "?"
  687. Default
  688. If _toker._tokeType<>TOKE_IDENT Err "Syntax error - expecting identifier."
  689. End Select
  690. Local id$=_toker._toke
  691. NextToke
  692. Return id
  693. End Method
  694. Method ParseIdentType:TIdentType()
  695. Local id$=ParseIdent()
  696. While CParse( "." )
  697. id:+"."+ParseIdent()
  698. Wend
  699. Local args:TType[]
  700. If CParse( "<" )
  701. Local nargs:Int
  702. Repeat
  703. Local arg:TType = ParseType()
  704. If args.Length=nargs args=args+ New TType[10]
  705. args[nargs]=arg
  706. nargs:+1
  707. Until Not CParse(",")
  708. args=args[..nargs]
  709. Parse ">"
  710. EndIf
  711. Return New TIdentType.Create( id,args )
  712. End Method
  713. Method NextToke$()
  714. Local toke$=_toke
  715. _tokeSpace=False
  716. Repeat
  717. _toke=_toker.NextToke()
  718. _tokeType=_toker.TokeType()
  719. If _tokeType<>TOKE_SPACE Exit
  720. _tokeSpace=True
  721. Forever
  722. If _tokeType=TOKE_KEYWORD _toke=_toke.ToLower()
  723. If toke="," SkipEols
  724. Return _toke
  725. End Method
  726. Method CParse:Int( toke$ )
  727. If _toker._toke.tolower()<>toke.tolower()
  728. Return False
  729. EndIf
  730. '_toker.
  731. NextToke
  732. Return True
  733. End Method
  734. Method CParseToker:Int( toker:TToker, toke$ )
  735. If toker._toke.ToLower()<>toke
  736. Return False
  737. EndIf
  738. NextTokeToker(toker)
  739. Return True
  740. End Method
  741. Method NextTokeToker$(toker:TToker)
  742. Repeat
  743. toker.NextToke()
  744. Until toker.tokeType()<>TOKE_SPACE
  745. Return toker._toke
  746. End Method
  747. Method SkipEols()
  748. Local found:Int = True
  749. While found
  750. found = False
  751. If CParse( "~n" )
  752. found = True
  753. End If
  754. If CParse("~r")
  755. found = True
  756. End If
  757. Wend
  758. SetErr
  759. End Method
  760. Method ParseStringLit$()
  761. If _toker._tokeType<>TOKE_STRINGLIT Err "Expecting string literal."
  762. Local str$=BmxUnquote( _toker._toke )
  763. '_toker.
  764. NextToke
  765. Return str
  766. End Method
  767. Method ParseFuncDecl:TFuncDecl( toke$,attrs:Long, returnType:TType = Null, classDecl:TClassDecl = Null )
  768. SetErr
  769. 'If toke Parse toke
  770. Local id$
  771. Local ty:TType
  772. Local meth:Long = attrs & FUNC_METHOD
  773. If Not returnType Then
  774. If attrs & FUNC_METHOD
  775. If _toker._toke.tolower() = "new"
  776. If attrs & DECL_EXTERN
  777. Err "Extern classes cannot have constructors"
  778. EndIf
  779. id=_toker._toke
  780. NextToke
  781. attrs:|FUNC_CTOR
  782. attrs:&~FUNC_METHOD
  783. ParseDeclType(attrs, True)
  784. Else
  785. If _toker._tokeType = TOKE_STRINGLIT Then
  786. id = ParseStringLit()
  787. Else
  788. id=ParseIdent()
  789. End If
  790. ty=ParseDeclType(attrs, True)
  791. EndIf
  792. Else
  793. id=ParseIdent()
  794. ty=ParseDeclType(attrs, True)
  795. EndIf
  796. End If
  797. Local args:TArgDecl[]
  798. Parse "("
  799. SkipEols
  800. If _toker._toke<>")"
  801. Local nargs:Int
  802. Repeat
  803. Local pos:Int, tokeType:Int
  804. pos = _toker._tokePos
  805. tokeType = _toker._tokeType
  806. 'DebugStop
  807. Local id$=ParseIdent()
  808. 'If id = "compareFunc" DebugStop
  809. Local ty:TType=ParseDeclType(attrs)
  810. Local init:TExpr
  811. If CParse( "(") Then
  812. 'DebugStop
  813. ' function pointer
  814. _toker.rollback(pos, tokeType)
  815. _toker._toke = id
  816. '_toker.NextToke()
  817. Local decl:TFuncDecl = ParseFuncDecl( id, FUNC_PTR | FUNC_INIT )
  818. ty = New TFunctionPtrType
  819. TFunctionPtrType(ty).func = decl
  820. End If
  821. If CParse("Var") Then
  822. ty = TType.MapToVarType(ty)
  823. End If
  824. If CParse( "=" ) Then
  825. 'DebugLog "TODO : parse default values..."
  826. If CParse("$") Then
  827. ' a string default
  828. init = ParseUnaryExpr()
  829. Else
  830. If Not TFunctionPtrType(ty) Then
  831. init = ParseUnaryExpr()
  832. If TArrayType(ty) Then
  833. If TConstExpr(init) And TConstExpr(init).value="bbEmptyArray" Then
  834. init = New TNullExpr.Create(TType.nullObjectType)
  835. End If
  836. Else If TObjectType(ty) Or TIdentType(ty) Then
  837. If TConstExpr(init) And TConstExpr(init).value="bbNullObject" Then
  838. init = New TNullExpr.Create(TType.nullObjectType)
  839. End If
  840. End If
  841. Else
  842. ' munged reference to default function pointer
  843. Local defaultFunc:String = ParseStringLit()
  844. Local func:TFuncDecl = TFuncDecl(TFunctionPtrType(ty).func.Copy())
  845. init = New TInvokeExpr.Create(func)
  846. func.munged = defaultFunc
  847. init.exprType = ty
  848. End If
  849. End If
  850. ' has a default value
  851. 'DebugStop
  852. 'init=ParseExpr()
  853. End If
  854. Local arg:TArgDecl=New TArgDecl.Create( id,ty,init )
  855. If args.Length=nargs args=args + New TArgDecl[10]
  856. args[nargs]=arg
  857. nargs:+1
  858. If _toker._toke=")" Exit
  859. Parse ","
  860. Forever
  861. args=args[..nargs]
  862. EndIf
  863. Parse ")"
  864. If returnType Then
  865. Return New TFuncDecl.CreateF(Null, returnType, args, 0)
  866. End If
  867. Local fdecl:TFuncDecl
  868. ' wait.. so everything until now was a function pointer return type, and we still have to process the function declaration...
  869. If _toke = "(" Then
  870. Local retTy:TType = New TFunctionPtrType
  871. TFunctionPtrType(retTy).func = New TFuncDecl.CreateF("",ty,args,attrs )
  872. TFunctionPtrType(retTy).func.attrs :| FUNC_PTR
  873. fdecl = ParseFuncDecl("", attrs, retTy)
  874. ty = retTy
  875. End If
  876. Local parsed:Int
  877. For Local i:Int = 0 Until _toke.Length
  878. Select _toke[i]
  879. Case Asc("F")
  880. attrs:| DECL_FINAL
  881. parsed = True
  882. Case Asc("W")
  883. attrs:| DECL_API_STDCALL
  884. parsed = True
  885. Case Asc("P")
  886. attrs:| DECL_PRIVATE
  887. parsed = True
  888. Case Asc("A")
  889. attrs:| DECL_ABSTRACT
  890. parsed = True
  891. Case Asc("O")
  892. attrs:| FUNC_OPERATOR
  893. parsed = True
  894. Case Asc("R")
  895. attrs:| DECL_PROTECTED
  896. parsed = True
  897. Case Asc("E")
  898. attrs:| DECL_EXPORT
  899. parsed = True
  900. End Select
  901. Next
  902. If parsed Then
  903. NextToke
  904. End If
  905. Local funcDecl:TFuncDecl
  906. If attrs & FUNC_CTOR Then
  907. funcDecl = New TNewDecl.CreateF( id,ty,args,attrs )
  908. TNewDecl(funcDecl).cdecl = classDecl
  909. Else
  910. If fdecl Then
  911. funcDecl = fdecl
  912. funcDecl.ident = id
  913. Else
  914. funcDecl = New TFuncDecl.CreateF( id,ty,args,attrs )
  915. End If
  916. End If
  917. funcDecl.retType = ty
  918. If CParse("&") Then
  919. funcDecl.attrs :| DECL_POINTER
  920. End If
  921. 'If funcDecl.IsExtern()
  922. If Not (funcDecl.attrs & (FUNC_PTR | FUNC_INIT)) Then
  923. ' funcDecl.munged=funcDecl.ident
  924. If CParse( "=" )
  925. If CParse("mem")
  926. If CParse(":")
  927. If CParse("p")
  928. If CParse("(") Then
  929. funcDecl.munged = ParseStringLit()
  930. Cparse(")")
  931. EndIf
  932. End If
  933. End If
  934. Else
  935. funcDecl.munged=ParseStringLit()
  936. End If
  937. End If
  938. End If
  939. ' read function cast stuff
  940. If CParse(":") Then
  941. ' ret type
  942. Local rt$=_toker._toke
  943. If CParse("unsigned") Then
  944. rt :+ " " + _toker._toke
  945. End If
  946. NextToke
  947. If CParse("*") Then
  948. rt:+ "*"
  949. If CParse("*") Then
  950. rt:+ "*"
  951. End If
  952. End If
  953. funcDecl.castTo = rt
  954. ' fname
  955. Local fn$=_toker._toke
  956. NextToke
  957. ' args
  958. Parse("(")
  959. If Not CParse(")") Then
  960. Local i:Int = 0
  961. Repeat
  962. Local at$=_toker._toke
  963. If CParse("const") Then
  964. at :+ " " + _toker._toke
  965. End If
  966. If CParse("unsigned") Then
  967. at :+ " " + _toker._toke
  968. End If
  969. NextToke
  970. If CParse("*") Then
  971. at:+ "*"
  972. If CParse("*") Then
  973. at:+ "*"
  974. End If
  975. End If
  976. ' function pointer
  977. If CParse("(") Then
  978. Parse("*")
  979. Parse(")")
  980. at :+ "(*)"
  981. Parse("(")
  982. at :+ "("
  983. While Not CParse(")")
  984. NextToke
  985. at :+ _toker._toke
  986. Wend
  987. at :+ ")"
  988. End If
  989. args[i].castTo = at
  990. If _toker._toke=")" Exit
  991. Parse ","
  992. i:+ 1
  993. Forever
  994. End If
  995. End If
  996. ' Return funcDecl
  997. 'EndIf
  998. If funcDecl.attrs & DECL_POINTER Then
  999. funcDecl.attrs :| FUNC_PTR
  1000. End If
  1001. 'If funcDecl.IsAbstract() Return funcDecl
  1002. If opt_def And funcDecl.attrs & DECL_EXPORT Then
  1003. _appInstance.exportDefs.AddLast(funcDecl)
  1004. End If
  1005. Return funcDecl
  1006. End Method
  1007. Method ParseDecl:TDecl( toke$,attrs:Long )
  1008. SetErr
  1009. Local pos:Int, tokeType:Int
  1010. pos = _toker._tokePos
  1011. tokeType = _toker._tokeType
  1012. Local id$=ParseIdent()
  1013. Local ty:TType
  1014. Local init:TExpr
  1015. If attrs & DECL_EXTERN
  1016. ty=ParseDeclType(attrs)
  1017. 'Else If CParse( ":=" )
  1018. ' init=ParseExpr()
  1019. Else
  1020. ty=ParseDeclType(attrs)
  1021. If CParse( "(") Then
  1022. 'DebugStop
  1023. ' function pointer
  1024. _toker.rollback(pos, tokeType)
  1025. _toker._toke = id
  1026. '_toker.NextToke()
  1027. Local decl:TFuncDecl = ParseFuncDecl( id, FUNC_PTR | FUNC_INIT )
  1028. ty = New TFunctionPtrType
  1029. TFunctionPtrType(ty).func = decl
  1030. If attrs & DECL_FIELD Then
  1031. decl.attrs :| FUNC_METHOD
  1032. End If
  1033. ' an array of function pointers?
  1034. If CParse( "&" ) Then
  1035. End If
  1036. If IstStaticArrayDef() Then
  1037. attrs :| DECL_STATIC
  1038. End If
  1039. While IsArrayDef(attrs & DECL_STATIC > 0)
  1040. ty = ParseArrayType(ty, attrs & DECL_STATIC > 0)
  1041. If CParse( "&" ) Then
  1042. End If
  1043. Wend
  1044. End If
  1045. If CParse("`") Then
  1046. If CParse("`") Then
  1047. attrs :| DECL_PROTECTED
  1048. Else
  1049. attrs :| DECL_PRIVATE
  1050. End If
  1051. End If
  1052. Rem
  1053. If CParse( "=" )
  1054. ' TODO init=ParseExpr()
  1055. If CParse("$") Then
  1056. ' string value
  1057. init = ParseUnaryExpr()
  1058. Else
  1059. init = ParseUnaryExpr()
  1060. End If
  1061. 'DebugLog "TODO : ParseExpression"
  1062. Else If CParse( "[" )
  1063. 'Local ln:TExpr=ParseExpr()
  1064. Parse "]"
  1065. 'While CParse( "[]" )
  1066. ' ty=New TArrayType.Create(ty)
  1067. 'Wend
  1068. 'init=New TNewArrayExpr.Create( ty,ln)
  1069. 'ty=New TArrayType.Create( ty )
  1070. Else If toke<>"const"
  1071. init=New TConstExpr.Create( ty,"" )
  1072. Else
  1073. Err "Constants must be initialized."
  1074. EndIf
  1075. End Rem
  1076. EndIf
  1077. Local decl:TValDecl
  1078. If attrs & DECL_GLOBAL
  1079. decl=New TGlobalDecl.Create( id,ty,init,attrs )
  1080. Else If attrs & DECL_FIELD
  1081. decl=New TFieldDecl.Create( id,ty,init,attrs )
  1082. If TFunctionPtrType(ty) Then
  1083. TFunctionPtrType(ty).func.attrs :| FUNC_FIELD
  1084. End If
  1085. Else If attrs & DECL_CONST
  1086. decl=New TConstDecl.Create( id,ty,init,attrs )
  1087. Else If attrs & DECL_LOCAL
  1088. decl=New TLocalDecl.Create( id,ty,init,attrs )
  1089. EndIf
  1090. 'DebugStop
  1091. ' If decl.IsExtern()
  1092. If CParse( "=" )
  1093. If CParse("mem")
  1094. ' Change to global
  1095. ' Until this point, it was "probably" a const, but now we know for sure
  1096. ' that it must be a global.
  1097. If attrs & DECL_CONST Then
  1098. attrs :| DECL_GLOBAL
  1099. attrs :~ DECL_CONST
  1100. decl=New TGlobalDecl.Create( id,ty,init,attrs )
  1101. End If
  1102. If CParse(":")
  1103. If CParse("p")
  1104. If CParse("(") Then
  1105. decl.munged = ParseStringLit()
  1106. ' for function pointers, ensure actual function reference is set too.
  1107. If TFunctionPtrType(decl.declTy) Then
  1108. TFunctionPtrType(decl.declTy).func.munged = decl.munged
  1109. End If
  1110. Parse(")")
  1111. EndIf
  1112. End If
  1113. Else
  1114. If CParse("(") Then
  1115. decl.munged = ParseStringLit()
  1116. Parse(")")
  1117. EndIf
  1118. End If
  1119. Else
  1120. If TStringType(ty)
  1121. If CParse("$") Then
  1122. decl.declInit = ParseUnaryExpr()
  1123. End If
  1124. Else
  1125. ' a default value ?
  1126. decl.declInit = ParseUnaryExpr()
  1127. End If
  1128. End If
  1129. Else
  1130. decl.munged=decl.ident
  1131. EndIf
  1132. ' EndIf
  1133. Return decl
  1134. End Method
  1135. ' replaces While CParse( "[]" ) sections, with support for multi-dimension arrays
  1136. Method ParseArrayType:TType(ty:TType, isStatic:Int = False)
  1137. If isStatic Then
  1138. Parse("[")
  1139. Local expr:TExpr = ParseUnaryExpr()
  1140. ty = New TArrayType.Create( ty )
  1141. TArrayType(ty).isStatic = True
  1142. TArrayType(ty).length = expr.Eval()
  1143. Parse("]")
  1144. Return ty
  1145. End If
  1146. While True
  1147. Local dims:Int = 1
  1148. If CParse("[]") Then
  1149. ty=New TArrayType.Create( ty )
  1150. Exit
  1151. End If
  1152. If Not CParse("[") Then
  1153. Exit
  1154. End If
  1155. While CParse( ",")
  1156. dims :+ 1
  1157. Wend
  1158. Parse "]"
  1159. ty=New TArrayType.Create( ty, dims )
  1160. Exit
  1161. Wend
  1162. Return ty
  1163. End Method
  1164. Method IstStaticArrayDef:Int()
  1165. Local toker:TToker=New TToker.Copy(_toker)
  1166. If Not CParseToker(toker, "[") Then
  1167. Return False
  1168. End If
  1169. If toker.TokeType() <> TOKE_INTLIT Then
  1170. Return False
  1171. End If
  1172. NextTokeToker(toker)
  1173. If Not CParseToker(toker, "]") Then
  1174. Return False
  1175. End If
  1176. Return True
  1177. End Method
  1178. Method IsArrayDef:Int(isStatic:Int = False)
  1179. Local isDef:Int = True
  1180. Local toker:TToker=New TToker.Copy(_toker)
  1181. If isStatic Then
  1182. If Not CParseToker(toker, "[") Then
  1183. Return False
  1184. End If
  1185. NextTokeToker(toker)
  1186. If Not CParseToker(toker, "]") Then
  1187. Return False
  1188. End If
  1189. Return True
  1190. End If
  1191. While True
  1192. If CParseToker(toker, "[]") Then
  1193. Exit
  1194. End If
  1195. If Not CParseToker(toker, "[") Then
  1196. isDef = False
  1197. Exit
  1198. End If
  1199. While CParseToker(toker, ",")
  1200. Wend
  1201. If Not CParseToker(toker, "]") Then
  1202. isDef = False
  1203. Exit
  1204. End If
  1205. Exit
  1206. Wend
  1207. Return isDef
  1208. End Method
  1209. Method ParseDeclType:TType(attrs:Long Var, fn:Int = False)
  1210. Local ty:TType
  1211. Select _toker._toke
  1212. 'Case "?"
  1213. ' NextToke
  1214. ' ty=TType.boolType
  1215. Case "%"
  1216. NextToke
  1217. ty=New TIntType
  1218. If CParse("%") Then
  1219. ty = New TLongType
  1220. ElseIf CParse("z") Then
  1221. ty = New TSizetType
  1222. ElseIf CParse("v") Then
  1223. ty = New TLongIntType
  1224. ElseIf CParse("e") Then
  1225. ty = New TULongIntType
  1226. ElseIf CParse("j") Then
  1227. ty = New TInt128Type
  1228. ElseIf CParse("w") Then
  1229. ty = New TWParamType
  1230. ElseIf CParse("x") Then
  1231. ty = New TLParamType
  1232. End If
  1233. If CParse("&") And Not (attrs & DECL_FIELD) Then
  1234. attrs :| DECL_GLOBAL
  1235. attrs :~ DECL_CONST
  1236. End If
  1237. ' pointer
  1238. While CParse( "*" )
  1239. ty = TType.MapToPointerType(ty)
  1240. Wend
  1241. Case "|"
  1242. NextToke
  1243. ty=New TUIntType
  1244. If CParse("|") Then
  1245. ty = New TULongType
  1246. End If
  1247. If CParse("&") And Not (attrs & DECL_FIELD) Then
  1248. attrs :| DECL_GLOBAL
  1249. attrs :~ DECL_CONST
  1250. End If
  1251. ' pointer
  1252. While CParse( "*" )
  1253. ty = TType.MapToPointerType(ty)
  1254. Wend
  1255. Case "#"
  1256. NextToke
  1257. ty=New TFloatType
  1258. If CParse("&") And Not (attrs & DECL_FIELD) Then
  1259. attrs :| DECL_GLOBAL
  1260. attrs :~ DECL_CONST
  1261. End If
  1262. ' pointer
  1263. While CParse( "*" )
  1264. ty = TType.MapToPointerType(ty)
  1265. Wend
  1266. Case "$"
  1267. NextToke
  1268. ty=New TStringType
  1269. If CParse("z") Then
  1270. ty._flags :| TType.T_CHAR_PTR
  1271. Else If CParse("w") Then
  1272. ty._flags :| TType.T_SHORT_PTR
  1273. End If
  1274. If CParse( "&" ) And Not (attrs & DECL_FIELD)
  1275. attrs :| DECL_GLOBAL
  1276. attrs :~ DECL_CONST
  1277. End If
  1278. Case "!"
  1279. NextToke
  1280. ty=New TDoubleType
  1281. If CParse("k") Then
  1282. ty = New TFloat128Type
  1283. Else If CParse("m") Then
  1284. ty = New TDouble128Type
  1285. Else If CParse("h") Then
  1286. ty = New TFloat64Type
  1287. End If
  1288. If CParse("&") And Not (attrs & DECL_FIELD) Then
  1289. attrs :| DECL_GLOBAL
  1290. attrs :~ DECL_CONST
  1291. End If
  1292. ' pointer
  1293. While CParse( "*" )
  1294. ty = TType.MapToPointerType(ty)
  1295. Wend
  1296. Case ":"
  1297. NextToke
  1298. ty=ParseNewType()
  1299. If CParse("*") Then
  1300. If TIdentType(ty) Then
  1301. ty = TType.MapToPointerType(ty)
  1302. While CParse( "*" )
  1303. ty = TType.MapToPointerType(ty)
  1304. Wend
  1305. End If
  1306. End If
  1307. CParse("&")
  1308. Case "?"
  1309. NextToke
  1310. attrs :| DECL_EXTERN
  1311. If CParse("?") Then
  1312. attrs :| CLASS_INTERFACE
  1313. End If
  1314. ty=ParseNewType()
  1315. If CParse("*") Then
  1316. If TIdentType(ty) Then
  1317. ty = TType.MapToPointerType(ty)
  1318. While CParse( "*" )
  1319. ty = TType.MapToPointerType(ty)
  1320. Wend
  1321. End If
  1322. End If
  1323. CParse("&")
  1324. Case "~~"
  1325. NextToke
  1326. attrs :| DECL_EXTERN | CLASS_STRUCT
  1327. ty=ParseNewType()
  1328. If CParse("*") Then
  1329. If TIdentType(ty) Then
  1330. ty = TType.MapToPointerType(ty)
  1331. While CParse( "*" )
  1332. ty = TType.MapToPointerType(ty)
  1333. Wend
  1334. End If
  1335. End If
  1336. CParse("&")
  1337. Case "@"
  1338. NextToke
  1339. ty=New TByteType
  1340. If CParse("@") Then
  1341. ty = New TShortType
  1342. End If
  1343. If CParse( "&" )
  1344. 'DebugStop
  1345. End If
  1346. ' pointer
  1347. While CParse( "*" )
  1348. ty = TType.MapToPointerType(ty)
  1349. Wend
  1350. Case "/"
  1351. NextToke
  1352. ty=ParseNewType()
  1353. If CParse("*") Then
  1354. If TIdentType(ty) Then
  1355. ty = TType.MapToPointerType(ty)
  1356. While CParse( "*" )
  1357. ty = TType.MapToPointerType(ty)
  1358. Wend
  1359. End If
  1360. End If
  1361. CParse("&")
  1362. ' TODO
  1363. ' Case "!" ' BaH Double
  1364. ' NextToke
  1365. ' ty=TType.doubleType
  1366. Default
  1367. 'If _module.IsStrict() Err "Illegal type expression."
  1368. 'DebugStop
  1369. If Not fn Then
  1370. ty=New TIntType
  1371. End If
  1372. End Select
  1373. If CParse( "&" ) Then
  1374. End If
  1375. If IstStaticArrayDef() Then
  1376. attrs :| DECL_STATIC
  1377. End If
  1378. While IsArrayDef(attrs & DECL_STATIC > 0)
  1379. ty = ParseArrayType(ty, attrs & DECL_STATIC > 0)
  1380. If CParse( "&" ) Then
  1381. End If
  1382. Wend
  1383. If CParse( "&" ) Then
  1384. End If
  1385. Return ty
  1386. End Method
  1387. Method ParseNewType:TType()
  1388. If CParse( "byte" ) Or CParse( "@" )
  1389. Local ty:TType = New TByteType
  1390. While CParse("ptr")
  1391. ty = TType.MapToPointerType(ty)
  1392. Wend
  1393. While CParse( "*" )
  1394. ty = TType.MapToPointerType(ty)
  1395. Wend
  1396. Return ty
  1397. End If
  1398. If CParse( "short" )
  1399. Local ty:TType = New TShortType
  1400. While CParse("ptr")
  1401. ty = TType.MapToPointerType(ty)
  1402. Wend
  1403. While CParse( "*" )
  1404. ty = TType.MapToPointerType(ty)
  1405. Wend
  1406. Return ty
  1407. End If
  1408. If CParse( "int" ) Or CParse( "%" )
  1409. Local ty:TType = New TIntType
  1410. While CParse("ptr")
  1411. ty = TType.MapToPointerType(ty)
  1412. Wend
  1413. While CParse( "*" )
  1414. ty = TType.MapToPointerType(ty)
  1415. Wend
  1416. Return ty
  1417. End If
  1418. If CParse( "uint" ) Or CParse( "|" )
  1419. Local ty:TType = New TUIntType
  1420. While CParse("ptr")
  1421. ty = TType.MapToPointerType(ty)
  1422. Wend
  1423. While CParse( "*" )
  1424. ty = TType.MapToPointerType(ty)
  1425. Wend
  1426. Return ty
  1427. End If
  1428. If CParse( "float" )
  1429. Local ty:TType = New TFloatType
  1430. While CParse("ptr")
  1431. ty = TType.MapToPointerType(ty)
  1432. Wend
  1433. While CParse( "*" )
  1434. ty = TType.MapToPointerType(ty)
  1435. Wend
  1436. Return ty
  1437. End If
  1438. If CParse( "string" ) Return New TStringType
  1439. If CParse( "object" ) Return New TIdentType.Create( "brl.classes.object" )
  1440. If CParse( "long" )
  1441. Local ty:TType = New TLongType
  1442. While CParse("ptr")
  1443. ty = TType.MapToPointerType(ty)
  1444. Wend
  1445. While CParse( "*" )
  1446. ty = TType.MapToPointerType(ty)
  1447. Wend
  1448. Return ty
  1449. End If
  1450. If CParse( "ulong" )
  1451. Local ty:TType = New TULongType
  1452. While CParse("ptr")
  1453. ty = TType.MapToPointerType(ty)
  1454. Wend
  1455. While CParse( "*" )
  1456. ty = TType.MapToPointerType(ty)
  1457. Wend
  1458. Return ty
  1459. End If
  1460. If CParse( "longint" )
  1461. Local ty:TType = New TLongType
  1462. While CParse("ptr")
  1463. ty = TType.MapToPointerType(ty)
  1464. Wend
  1465. While CParse( "*" )
  1466. ty = TType.MapToPointerType(ty)
  1467. Wend
  1468. Return ty
  1469. End If
  1470. If CParse( "ulongint" )
  1471. Local ty:TType = New TULongIntType
  1472. While CParse("ptr")
  1473. ty = TType.MapToPointerType(ty)
  1474. Wend
  1475. While CParse( "*" )
  1476. ty = TType.MapToPointerType(ty)
  1477. Wend
  1478. Return ty
  1479. End If
  1480. If CParse( "double" )
  1481. Local ty:TType = New TDoubleType
  1482. While CParse("ptr")
  1483. ty = TType.MapToPointerType(ty)
  1484. Wend
  1485. While CParse( "*" )
  1486. ty = TType.MapToPointerType(ty)
  1487. Wend
  1488. Return ty
  1489. End If
  1490. If CParse( "size_t" )
  1491. Local ty:TType = New TSizeTType
  1492. While CParse("ptr")
  1493. ty = TType.MapToPointerType(ty)
  1494. Wend
  1495. While CParse( "*" )
  1496. ty = TType.MapToPointerType(ty)
  1497. Wend
  1498. Return ty
  1499. End If
  1500. If CParse( "int128" )
  1501. Local ty:TType = New TInt128Type
  1502. While CParse("ptr")
  1503. ty = TType.MapToPointerType(ty)
  1504. Wend
  1505. While CParse( "*" )
  1506. ty = TType.MapToPointerType(ty)
  1507. Wend
  1508. Return ty
  1509. End If
  1510. If CParse( "float64" )
  1511. Local ty:TType = New TFloat64Type
  1512. While CParse("ptr")
  1513. ty = TType.MapToPointerType(ty)
  1514. Wend
  1515. While CParse( "*" )
  1516. ty = TType.MapToPointerType(ty)
  1517. Wend
  1518. Return ty
  1519. End If
  1520. If CParse( "float128" )
  1521. Local ty:TType = New TFloat128Type
  1522. While CParse("ptr")
  1523. ty = TType.MapToPointerType(ty)
  1524. Wend
  1525. While CParse( "*" )
  1526. ty = TType.MapToPointerType(ty)
  1527. Wend
  1528. Return ty
  1529. End If
  1530. If CParse( "double128" )
  1531. Local ty:TType = New TDouble128Type
  1532. While CParse("ptr")
  1533. ty = TType.MapToPointerType(ty)
  1534. Wend
  1535. While CParse( "*" )
  1536. ty = TType.MapToPointerType(ty)
  1537. Wend
  1538. Return ty
  1539. End If
  1540. If CParse( "wparam" )
  1541. Local ty:TType = New TWParamType
  1542. While CParse("ptr")
  1543. ty = TType.MapToPointerType(ty)
  1544. Wend
  1545. While CParse( "*" )
  1546. ty = TType.MapToPointerType(ty)
  1547. Wend
  1548. Return ty
  1549. End If
  1550. If CParse( "lparam" )
  1551. Local ty:TType = New TLParamType
  1552. While CParse("ptr")
  1553. ty = TType.MapToPointerType(ty)
  1554. Wend
  1555. While CParse( "*" )
  1556. ty = TType.MapToPointerType(ty)
  1557. Wend
  1558. Return ty
  1559. End If
  1560. Return ParseIdentType()
  1561. End Method
  1562. Method ApplyFunctionAttributes(classDecl:TClassDecl, attrs:Long)
  1563. For Local decl:TFuncDecl = EachIn classDecl._decls
  1564. decl.attrs :| attrs
  1565. Next
  1566. End Method
  1567. Method SetErr()
  1568. If _toker.Path()
  1569. _errInfo=FormatError(_toker.Path(), _toker.Line(), 0)
  1570. EndIf
  1571. End Method
  1572. Method ParseType:TType()
  1573. Local ty:TType=CParsePrimitiveType()
  1574. If ty Return ty
  1575. Return ParseIdentType()
  1576. End Method
  1577. Method CParsePrimitiveType:TType()
  1578. If CParse( "string" ) Return TType.stringType
  1579. If CParse( "object" ) Return New TIdentType.Create( "brl.classes.object" )
  1580. Local ty:TType
  1581. If CParse( "short" )
  1582. ty = New TShortType
  1583. Else If CParse( "byte" )
  1584. ty = New TByteType
  1585. Else If CParse( "int" )
  1586. ty = New TIntType
  1587. Else If CParse( "uint" )
  1588. ty = New TUIntType
  1589. Else If CParse( "float" )
  1590. ty = New TFloatType
  1591. Else If CParse( "long" )
  1592. ty = New TLongType
  1593. Else If CParse( "ulong" )
  1594. ty = New TULongType
  1595. Else If CParse( "longint" )
  1596. ty = New TLongIntType
  1597. Else If CParse( "ulongint" )
  1598. ty = New TULongIntType
  1599. Else If CParse( "double" )
  1600. ty = New TDoubleType
  1601. Else If CParse( "size_t" )
  1602. ty = New TSizeTType
  1603. Else If CParse( "int128" ) Then
  1604. If opt_arch <> "x64" Err "Intrinsic types only available on x64"
  1605. ty = New TInt128Type
  1606. Else If CParse( "float128" ) Then
  1607. If opt_arch <> "x64" Err "Intrinsic types only available on x64"
  1608. ty = New TFloat128Type
  1609. Else If CParse( "double128" ) Then
  1610. If opt_arch <> "x64" Err "Intrinsic types only available on x64"
  1611. ty = New TDouble128Type
  1612. Else If CParse( "float64" ) Then
  1613. If opt_arch <> "x64" Err "Intrinsic types only available on x64"
  1614. ty = New TFloat64Type
  1615. Else If CParse( "wparam" ) Then
  1616. If opt_platform <> "win32" Err "WParam types only available on Win32"
  1617. ty = New TWParamType
  1618. Else If CParse( "lparam" ) Then
  1619. If opt_platform <> "win32" Err "LParam types only available on Win32"
  1620. ty = New TLParamType
  1621. End If
  1622. While CParse("ptr")
  1623. ty = TType.MapToPointerType(ty)
  1624. Wend
  1625. Return ty
  1626. End Method
  1627. End Type