iparser.bmx 45 KB

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