iparser.bmx 44 KB

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