iparser.bmx 40 KB

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