iparser.bmx 46 KB

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