iparser.bmx 42 KB

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