iparser.bmx 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653
  1. ' Copyright (c) 2013-2016 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 "toker.bmx"
  27. Const DECL_GLOBAL:Int = $10
  28. Const DECL_FIELD:Int = $20
  29. Const DECL_CONST:Int = $40
  30. Const DECL_LOCAL:Int = $80
  31. Type TIParser
  32. Field _toker:TToker
  33. Field _toke$
  34. Field _tokeType:Int
  35. Field _tokeSpace:Int
  36. Field _tokerStack:TList=New TList'<TToker>
  37. Method ParseModuleImport:Int(pmod:TModuleDecl, modpath:String, path:String, imp:String = Null, iData:String = Null, attrs:Int = 0, relPath:String = "", isFileImport:Int = 0)
  38. Const STATE_CLASS:Int = 1
  39. If Not modpath Then
  40. modpath = imp
  41. End If
  42. ' already imported??
  43. If _appInstance.IsImported(modpath)
  44. ' add import to the scope (so we can find decls in it later)
  45. ' but don't add it if pmod is the apps' main module
  46. If _appInstance.mainModule <> pmod Then
  47. pmod.AddImport(modpath, _appInstance.globalImports.ValueForKey(modpath))
  48. End If
  49. Return False
  50. Else If imp Then
  51. ' if "imp" is set, this is a file import. We need to check for it too, or we may end up importing it twice.
  52. If _appInstance.IsImported(imp)
  53. ' add import to the scope (so we can find decls in it later)
  54. ' but don't add it if pmod is the apps' main module
  55. If _appInstance.mainModule <> pmod Then
  56. pmod.AddImport(imp, _appInstance.globalImports.ValueForKey(imp))
  57. End If
  58. Return False
  59. End If
  60. End If
  61. Local prefix:String
  62. If isFileImport And opt_buildtype = BUILDTYPE_APP Then
  63. prefix = "m_"
  64. End If
  65. Local _mod:TModuleDecl = New TModuleDecl.Create(prefix + modpath, "bb" + modpath, path, attrs)
  66. Select modpath
  67. Case "brl.classes", "brl.blitzkeywords"
  68. _mod.UpdateFilePath(_mod.filepath + "." + modpath)
  69. End Select
  70. _mod.declImported = True
  71. _mod.relpath = relPath
  72. _mod.pmod = pmod
  73. If modpath = "brl.blitz" Then
  74. If pmod.imported.Contains(modpath) Then
  75. _mod = TModuleDecl(pmod.imported.ValueForKey(modpath))
  76. Else
  77. pmod.AddImport(modpath, _mod)
  78. End If
  79. ' import Object and String definitions
  80. Local par:TIParser = New TIParser
  81. If FileType(modulepath("brl.blitz") + "\blitz_classes." + opt_platform + ".i") Then
  82. par.ParseModuleImport(_mod, "brl.classes", modulepath("brl.blitz"), modulepath("brl.blitz") + "\blitz_classes." + opt_platform + ".i")
  83. Else
  84. par.ParseModuleImport(_mod, "brl.classes", modulepath("brl.blitz"), modulepath("brl.blitz") + "\blitz_classes.i")
  85. End If
  86. ' set up built-in keywords
  87. par = New TIParser
  88. par.ParseModuleImport(_mod, "brl.blitzkeywords", "", "", MakeKeywords())
  89. Else
  90. pmod.AddImport(modpath, _mod)
  91. End If
  92. _appInstance.globalImports.Insert(modpath, _mod)
  93. Local ipath:String
  94. 'Local ipath:String = path + "\" + ModuleIdent(modpath) + ".release.macos.x86.i"
  95. If imp Then
  96. ipath = imp
  97. ' add to imports
  98. pmod.AddImport(ipath, _mod)
  99. _appInstance.globalImports.Insert(ipath, _mod)
  100. Else
  101. ipath = path + "/" + ModuleIdent(modpath) + FileMung() + ".i"
  102. End If
  103. If Not iData Then
  104. If Not FileType(ipath) Then
  105. Err "Can't find interface for module '" + modpath + "'"
  106. Return False
  107. End If
  108. 'Local ifile:String[] = LoadString(ipath).Split("~n")
  109. _toker = New TToker.Create( ipath,LoadString( ipath ) )
  110. Else
  111. _toker = New TToker.Create( ipath, iData)
  112. End If
  113. Local toker:TToker = _toker
  114. Repeat
  115. Local pos:Int
  116. pos = toker._tokePos
  117. toker.NextToke
  118. Local line:Int
  119. Local state:Int
  120. Local class:TClassDecl
  121. Local stm:String
  122. Select toker.Toke().ToLower()
  123. Case "superstrict"
  124. _mod.attrs :| MODULE_SUPERSTRICT
  125. Continue
  126. Case "import"
  127. toker.NextToke()
  128. If toker.TokeType()=TOKE_SPACE toker.NextToke()
  129. ' skip non-module imports
  130. If toker.TokeType()=TOKE_STRINGLIT
  131. Local iRelPath:String = ParseStringLit()
  132. SetErr
  133. If iRelPath.EndsWith(".bmx") Then
  134. Local origPath:String = RealPath(ExtractDir(path) + "/" + iRelPath)
  135. Local iPath:String = OutputFilePath(origPath, FileMung(), "i")
  136. If FileType( iPath )<>FILETYPE_FILE
  137. Err "File '"+ iPath +"' not found."
  138. EndIf
  139. If _mod.imported.Contains( iPath ) Continue
  140. Local modpath:String
  141. If opt_buildtype = BUILDTYPE_MODULE Then
  142. Local dir:String = ExtractDir(origPath).ToLower()
  143. dir = dir[dir.findLast("/") + 1..]
  144. If dir.EndsWith(".mod") Then
  145. dir = ""
  146. Else
  147. dir :+ "_"
  148. End If
  149. Local file:String = StripDir(origPath).ToLower()
  150. modpath = opt_modulename + "_" + dir + StripExt(file)
  151. 'sanitize the path, remove non-allowed chars
  152. modpath = TStringHelper.Sanitize(modpath.ToLower())
  153. Else
  154. ' todo file imports for apps
  155. 'internalErr
  156. End If
  157. ' Local mdecl:TDecl=TDecl(pmod.GetDecl( modpath ))
  158. ' If Not mdecl
  159. New TIParser.ParseModuleImport( _mod, modpath, origPath, iPath, , , iRelPath)
  160. ' Else
  161. ' _mod.imported.Insert(modpath, mdecl)
  162. ' EndIf
  163. Else
  164. If iRelPath.StartsWith("-") Then
  165. If Not _mod.fileImports.Contains(iRelPath) Then
  166. _mod.fileImports.AddLast(iRelPath)
  167. End If
  168. End If
  169. End If
  170. Else
  171. Local m:String = toker._toke
  172. toker.NextToke()
  173. Parse(".")
  174. m :+ "." + toker._toke
  175. SetErr
  176. Local mdecl:TDecl=TDecl(pmod.GetDecl( m ))
  177. If Not mdecl
  178. Local path:String = modulepath(m)
  179. ' parse the imported module
  180. New TIParser.ParseModuleImport( _mod, m, path )
  181. Else
  182. _mod.AddImport(m, mdecl)
  183. EndIf
  184. End If
  185. Continue
  186. Case "moduleinfo"
  187. toker.nextToke()
  188. If toker.TokeType()=TOKE_SPACE toker.NextToke()
  189. Continue
  190. Case "~r", "~n"
  191. Continue
  192. Default
  193. stm = toker.Toke()
  194. Local v:String = toker.NextToke()
  195. Select v
  196. Case "^"
  197. toker.rollback(pos)
  198. toker.NextToke()
  199. ' class decl
  200. class = ParseClassDecl( stm,0 )
  201. class.declImported = True
  202. _mod.InsertDecl(class)
  203. If CParse("F")
  204. class.attrs :| DECL_FINAL
  205. Else If CParse("A")
  206. class.attrs :| DECL_ABSTRACT
  207. Else If CParse("S")
  208. class.attrs :| CLASS_STRUCT
  209. Else If CParse("AF")
  210. class.attrs :| DECL_ABSTRACT | DECL_FINAL
  211. Else If CParse("E")
  212. class.attrs :| DECL_EXTERN
  213. ApplyFunctionAttributes(class, DECL_EXTERN)
  214. Else If CParse("EW")
  215. class.attrs :| DECL_EXTERN | DECL_API_WIN32
  216. ApplyFunctionAttributes(class, DECL_EXTERN | DECL_API_WIN32)
  217. Else If CParse("AI")
  218. class.attrs :| CLASS_INTERFACE | DECL_ABSTRACT
  219. ApplyFunctionAttributes(class, DECL_ABSTRACT)
  220. Else If CParse("EI")
  221. class.attrs :| DECL_EXTERN | CLASS_INTERFACE
  222. ApplyFunctionAttributes(class, DECL_EXTERN | DECL_ABSTRACT)
  223. Else If CParse("EIW")
  224. class.attrs :| DECL_EXTERN | CLASS_INTERFACE | DECL_API_WIN32
  225. ApplyFunctionAttributes(class, DECL_EXTERN | DECL_ABSTRACT | DECL_API_WIN32)
  226. Else If CParse("ES")
  227. class.attrs :| DECL_EXTERN | CLASS_STRUCT
  228. Else If CParse("ESW")
  229. class.attrs :| DECL_EXTERN | CLASS_STRUCT | DECL_API_WIN32
  230. End If
  231. 'DebugStop
  232. If CParse( "=" )
  233. 'DebugStop
  234. If Not class.IsExtern() Then
  235. class.munged=ParseStringLit()
  236. If class.ident <> "String" Then
  237. For Local fdecl:TFieldDecl = EachIn class._decls
  238. fdecl.munged = "_" + class.munged + "_" + fdecl.ident
  239. fdecl.munged = fdecl.munged.ToLower()
  240. Next
  241. End If
  242. Else
  243. Parse "0"
  244. If Not class.munged Then
  245. class.munged = class.ident
  246. End If
  247. End If
  248. EndIf
  249. 'state = STATE_CLASS
  250. 'Exit
  251. ' Case "%"
  252. Default
  253. If toker._tokeType = TOKE_EOF
  254. 'DebugStop
  255. Exit
  256. End If
  257. Local a:Int
  258. Local ty:TType = ParseDeclType(a)
  259. If CParse("(") Then
  260. toker.rollback(pos)
  261. toker.NextToke()
  262. Local decl:TFuncDecl = ParseFuncDecl( _toke, 0 )
  263. decl.declImported = True
  264. ' an array of function pointers?
  265. If CParse( "&" ) Then
  266. End If
  267. While IsArrayDef()
  268. ty = ParseArrayType(ty)
  269. If CParse( "&" ) Then
  270. End If
  271. Wend
  272. If decl.attrs & FUNC_PTR Then
  273. Local fpty:TType = New TFunctionPtrType
  274. TFunctionPtrType(fpty).func = decl
  275. If TArrayType(ty) Then
  276. TArrayType(ty).elemType = fpty
  277. Else
  278. ty = fpty
  279. End If
  280. 'Local declInit:TExpr = decl.declInit
  281. 'decl.declInit = Null
  282. Local gdecl:TGlobalDecl = New TGlobalDecl.Create( decl.ident,ty, Null, DECL_GLOBAL )
  283. gdecl.munged = decl.munged
  284. _mod.InsertDecl gdecl
  285. gdecl.declImported = True
  286. If CParse( "=" )
  287. If CParse("mem")
  288. If CParse(":")
  289. If CParse("p")
  290. If CParse("(") Then
  291. gdecl.munged = ParseStringLit()
  292. ' for function pointers, ensure actual function reference is set too.
  293. 'If TFunctionPtrType(gdecl.declTy) Then
  294. ' TFunctionPtrType(gdecl.declTy).func.munged = gdecl.munged
  295. 'Else If TArrayType(gdecl.declTy) Then
  296. '
  297. 'End If
  298. TFunctionPtrType(fpty).func.munged = gdecl.munged
  299. Parse(")")
  300. EndIf
  301. End If
  302. Else
  303. If CParse("(") Then
  304. gdecl.munged = ParseStringLit()
  305. Parse(")")
  306. EndIf
  307. End If
  308. Else
  309. If TStringType(ty)
  310. If CParse("$") Then
  311. gdecl.declInit = ParseUnaryExpr()
  312. End If
  313. Else
  314. ' a default value ?
  315. gdecl.declInit = ParseUnaryExpr()
  316. End If
  317. End If
  318. End If
  319. Else
  320. _mod.InsertDecl decl
  321. End If
  322. Else
  323. toker.rollback(pos)
  324. toker.NextToke()
  325. Local decl:TDecl = ParseDecl( _toke, DECL_CONST | DECL_EXTERN)'DECL_GLOBAL | DECL_EXTERN )
  326. _mod.InsertDecl decl
  327. decl.declImported = True
  328. End If
  329. End Select
  330. End Select
  331. line :+ 1
  332. Forever
  333. Return True
  334. End Method
  335. Method ParseUnaryExpr:TExpr()
  336. SkipEols
  337. Local op$=_toke
  338. Select op
  339. Case "+","-","~~","not"
  340. NextToke
  341. Local expr:TExpr=ParseUnaryExpr()
  342. Return New TUnaryExpr.Create( op,expr )
  343. End Select
  344. Return ParsePrimaryExpr( False )
  345. End Method
  346. Method ParsePrimaryExpr:TExpr( stmt:Int )
  347. Local expr:TExpr
  348. Select _tokeType
  349. 'Case TOKE_IDENT
  350. ' expr=New TIdentExpr.Create( ParseIdent() )
  351. Case TOKE_INTLIT
  352. expr=New TConstExpr.Create( New TIntType,_toke )
  353. NextToke
  354. Case TOKE_LONGLIT
  355. expr=New TConstExpr.Create( New TLongType,_toke )
  356. NextToke
  357. Case TOKE_FLOATLIT
  358. Local value:String = _toke
  359. NextToke
  360. If CParse("!") Then
  361. expr=New TConstExpr.Create( New TDoubleType,value )
  362. Else
  363. CParse("#")
  364. expr=New TConstExpr.Create( New TFloatType,value )
  365. End If
  366. Case TOKE_STRINGLIT
  367. expr=New TConstExpr.Create( New TStringType,BmxUnquote( _toke, True ) )
  368. NextToke
  369. Case TOKE_IDENT
  370. If _toke = "nan" Or _toke = "inf" Then
  371. Local value:String = _toke
  372. NextToke
  373. If CParse("!") Then
  374. expr=New TConstExpr.Create( New TDoubleType,value )
  375. Else
  376. CParse("#")
  377. expr=New TConstExpr.Create( New TFloatType,value )
  378. End If
  379. Else
  380. Err "Syntax error - unexpected token '"+_toke+"'"
  381. End If
  382. Default
  383. Err "Syntax error - unexpected token '"+_toke+"'"
  384. End Select
  385. Return expr
  386. End Method
  387. Method ParseClassDecl:TClassDecl( toke$,attrs:Int )
  388. SetErr
  389. 'If toke Parse toke
  390. Local id$=ParseIdent()
  391. Local args:String[]
  392. Local superTy:TIdentType
  393. Local imps:TIdentType[]
  394. If CParse( "^" )
  395. If CParse( "null" )
  396. superTy=Null
  397. Else
  398. superTy=ParseIdentType()
  399. 'If superTy.ident <> "Object" Then
  400. ' superTy = TIdentType(superTy.Semant())
  401. 'EndIf
  402. EndIf
  403. Else
  404. superTy = New TIdentType.Create( "brl.classes.object" )
  405. EndIf
  406. ' implements
  407. If CParse("@") Then
  408. Local nimps:Int
  409. Repeat
  410. If imps.Length=nimps imps=imps + New TIdentType[10]
  411. imps[nimps]=ParseIdentType()
  412. nimps:+1
  413. Until Not CParse(",")
  414. imps=imps[..nimps]
  415. End If
  416. Local classDecl:TClassDecl=New TClassDecl.Create( id,args,superTy,imps,attrs )
  417. If classDecl.IsExtern()
  418. classDecl.munged=classDecl.ident
  419. If CParse( "=" ) classDecl.munged=ParseStringLit()
  420. EndIf
  421. 'If classDecl.IsTemplateArg() Return classDecl
  422. Local decl_attrs:Int=(attrs & DECL_EXTERN)
  423. Local method_attrs:Int=decl_attrs
  424. If attrs & CLASS_INTERFACE method_attrs:|DECL_ABSTRACT
  425. Repeat
  426. SkipEols
  427. 'If IsSpace(Asc(_toker._toke))
  428. ' _toker.NextToke
  429. 'End If
  430. Select _toker._toke
  431. Case "{"
  432. '_toker.
  433. NextToke
  434. Case "}"
  435. '_toker.
  436. NextToke
  437. Exit
  438. Case "-" ' method
  439. 'DebugStop
  440. '_toker.
  441. NextToke
  442. Local decl:TFuncDecl = ParseFuncDecl( _toke,method_attrs|FUNC_METHOD )
  443. 'If decl.IsCtor() decl.retTypeExpr=New TObjectType.Create( classDecl )
  444. classDecl.InsertDecl decl
  445. Case "+" ' function
  446. NextToke
  447. Local decl:TFuncDecl = ParseFuncDecl( _toke,method_attrs )
  448. 'If decl.IsCtor() decl.retTypeExpr=New TObjectType.Create( classDecl )
  449. classDecl.InsertDecl decl
  450. Case "." ' field
  451. NextToke
  452. decl_attrs :| DECL_FIELD
  453. Local decl:TDecl= ParseDecl( _toke,decl_attrs )
  454. classDecl.InsertDecl decl
  455. Rem
  456. Case "private"
  457. NextToke
  458. decl_attrs=decl_attrs | DECL_PRIVATE
  459. Case "public"
  460. NextToke
  461. decl_attrs=decl_attrs & ~DECL_PRIVATE
  462. Case "const","global","field"
  463. If (attrs & CLASS_INTERFACE) And _toke<>"const"
  464. Err "Interfaces can only contain constants and methods."
  465. EndIf
  466. classDecl.InsertDecls ParseDecls( _toke,decl_attrs )
  467. Case "method"
  468. Local decl:TFuncDecl=ParseFuncDecl( _toke,method_attrs )
  469. If decl.IsCtor() decl.retTypeExpr=New TObjectType.Create( classDecl )
  470. classDecl.InsertDecl decl
  471. Case "function"
  472. If (attrs & CLASS_INTERFACE) And _toke<>"const"
  473. Err "Interfaces can only contain constants and methods."
  474. EndIf
  475. Local decl:TFuncDecl=ParseFuncDecl( _toke,decl_attrs )
  476. classDecl.InsertDecl decl
  477. End Rem
  478. 'Default
  479. ' Err "Syntax error - expecting class member declaration."
  480. End Select
  481. If _toker._tokeType = TOKE_IDENT Then
  482. ' Const / Global?
  483. 'NextToke
  484. 'decl_attrs :| DECL_CONST
  485. Local decl:TDecl= ParseDecl( _toke,decl_attrs | DECL_CONST)
  486. classDecl.InsertDecl decl
  487. End If
  488. Forever
  489. If toke CParse toke
  490. Return classDecl
  491. End Method
  492. Method Parse( toke$ )
  493. If Not CParse( toke )
  494. Err "Syntax error - expecting '"+toke+"'."
  495. EndIf
  496. End Method
  497. Method ParseIdent$()
  498. Select _toker._toke.tolower()
  499. Case "@" _toker.NextToke
  500. Case "string","___array","object"
  501. Default
  502. If _toker._tokeType<>TOKE_IDENT Err "Syntax error - expecting identifier."
  503. End Select
  504. Local id$=_toker._toke
  505. NextToke
  506. Return id
  507. End Method
  508. Method ParseIdentType:TIdentType()
  509. Local id$=ParseIdent()
  510. While CParse( "." )
  511. id:+"."+ParseIdent()
  512. Wend
  513. Local args:TIdentType[]
  514. Return New TIdentType.Create( id,args )
  515. End Method
  516. Method NextToke$()
  517. Local toke$=_toke
  518. _tokeSpace=False
  519. Repeat
  520. _toke=_toker.NextToke()
  521. _tokeType=_toker.TokeType()
  522. If _tokeType<>TOKE_SPACE Exit
  523. _tokeSpace=True
  524. Forever
  525. If _tokeType=TOKE_KEYWORD _toke=_toke.ToLower()
  526. If toke="," SkipEols
  527. Return _toke
  528. End Method
  529. Method CParse:Int( toke$ )
  530. If _toker._toke.tolower()<>toke.tolower()
  531. Return False
  532. EndIf
  533. '_toker.
  534. NextToke
  535. Return True
  536. End Method
  537. Method CParseToker:Int( toker:TToker, toke$ )
  538. If toker._toke.ToLower()<>toke
  539. Return False
  540. EndIf
  541. NextTokeToker(toker)
  542. Return True
  543. End Method
  544. Method NextTokeToker$(toker:TToker)
  545. Repeat
  546. toker.NextToke()
  547. Until toker.tokeType()<>TOKE_SPACE
  548. Return toker._toke
  549. End Method
  550. Method SkipEols()
  551. Local found:Int = True
  552. While found
  553. found = False
  554. If CParse( "~n" )
  555. found = True
  556. End If
  557. If CParse("~r")
  558. found = True
  559. End If
  560. Wend
  561. SetErr
  562. End Method
  563. Method ParseStringLit$()
  564. If _toker._tokeType<>TOKE_STRINGLIT Err "Expecting string literal."
  565. Local str$=BmxUnquote( _toker._toke, True )
  566. '_toker.
  567. NextToke
  568. Return str
  569. End Method
  570. Method ParseFuncDecl:TFuncDecl( toke$,attrs:Int, returnType:TType = Null )
  571. SetErr
  572. 'If toke Parse toke
  573. Local id$
  574. Local ty:TType
  575. Local meth:Int = attrs & FUNC_METHOD
  576. If Not returnType Then
  577. If attrs & FUNC_METHOD
  578. If _toker._toke.tolower() = "new"
  579. If attrs & DECL_EXTERN
  580. Err "Extern classes cannot have constructors"
  581. EndIf
  582. id=_toker._toke
  583. NextToke
  584. attrs:|FUNC_CTOR
  585. attrs:&~FUNC_METHOD
  586. ty=ParseDeclType(attrs, True)
  587. Else
  588. If _toker._tokeType = TOKE_STRINGLIT Then
  589. id = ParseStringLit()
  590. Else
  591. id=ParseIdent()
  592. End If
  593. ty=ParseDeclType(attrs, True)
  594. EndIf
  595. Else
  596. id=ParseIdent()
  597. ty=ParseDeclType(attrs, True)
  598. EndIf
  599. End If
  600. Local args:TArgDecl[]
  601. Parse "("
  602. SkipEols
  603. If _toker._toke<>")"
  604. Local nargs:Int
  605. Repeat
  606. Local pos:Int, tokeType:Int
  607. pos = _toker._tokePos
  608. tokeType = _toker._tokeType
  609. 'DebugStop
  610. Local id$=ParseIdent()
  611. 'If id = "compareFunc" DebugStop
  612. Local ty:TType=ParseDeclType(attrs)
  613. Local init:TExpr
  614. If CParse( "(") Then
  615. 'DebugStop
  616. ' function pointer
  617. _toker.rollback(pos, tokeType)
  618. _toker._toke = id
  619. '_toker.NextToke()
  620. Local decl:TFuncDecl = ParseFuncDecl( id, FUNC_PTR | FUNC_INIT )
  621. ty = New TFunctionPtrType
  622. TFunctionPtrType(ty).func = decl
  623. End If
  624. If CParse("Var") Then
  625. ty = TType.MapToVarType(ty)
  626. End If
  627. If CParse( "=" ) Then
  628. 'DebugLog "TODO : parse default values..."
  629. If CParse("$") Then
  630. ' a string default
  631. init = ParseUnaryExpr()
  632. Else
  633. If Not TFunctionPtrType(ty) Then
  634. init = ParseUnaryExpr()
  635. If TArrayType(ty) Then
  636. If TConstExpr(init) And TConstExpr(init).value="bbEmptyArray" Then
  637. init = New TNullExpr.Create(TType.nullObjectType)
  638. End If
  639. Else If TObjectType(ty) Or TIdentType(ty) Then
  640. If TConstExpr(init) And TConstExpr(init).value="bbNullObject" Then
  641. init = New TNullExpr.Create(TType.nullObjectType)
  642. End If
  643. End If
  644. Else
  645. ' munged reference to default function pointer
  646. Local defaultFunc:String = ParseStringLit()
  647. Local func:TFuncDecl = TFuncDecl(TFunctionPtrType(ty).func.Copy())
  648. init = New TInvokeExpr.Create(func)
  649. func.munged = defaultFunc
  650. init.exprType = ty
  651. End If
  652. End If
  653. ' has a default value
  654. 'DebugStop
  655. 'init=ParseExpr()
  656. End If
  657. Local arg:TArgDecl=New TArgDecl.Create( id,ty,init )
  658. If args.Length=nargs args=args + New TArgDecl[10]
  659. args[nargs]=arg
  660. nargs:+1
  661. If _toker._toke=")" Exit
  662. Parse ","
  663. Forever
  664. args=args[..nargs]
  665. EndIf
  666. Parse ")"
  667. If returnType Then
  668. Return New TFuncDecl.CreateF(Null, returnType, args, 0)
  669. End If
  670. Local fdecl:TFuncDecl
  671. ' wait.. so everything until now was a function pointer return type, and we still have to process the function declaration...
  672. If _toke = "(" Then
  673. Local retTy:TType = New TFunctionPtrType
  674. TFunctionPtrType(retTy).func = New TFuncDecl.CreateF("",ty,args,attrs )
  675. TFunctionPtrType(retTy).func.attrs :| FUNC_PTR
  676. fdecl = ParseFuncDecl("", attrs, retTy)
  677. ty = retTy
  678. End If
  679. Repeat
  680. If CParse( "F" )
  681. attrs:|DECL_FINAL
  682. Else If CParse( "FW" )
  683. attrs:|DECL_FINAL | DECL_API_WIN32
  684. Else If CParse( "FP" )
  685. attrs:|DECL_FINAL|DECL_PRIVATE
  686. Else If CParse( "FPW" )
  687. attrs:|DECL_FINAL|DECL_PRIVATE| DECL_API_WIN32
  688. Else If CParse( "FR" )
  689. attrs:|DECL_FINAL|DECL_PROTECTED
  690. Else If CParse( "FRW" )
  691. attrs:|DECL_FINAL|DECL_PROTECTED| DECL_API_WIN32
  692. Else If CParse( "A" )
  693. attrs:|DECL_ABSTRACT
  694. Else If CParse( "AW" )
  695. attrs:|DECL_ABSTRACT | DECL_API_WIN32
  696. Else If CParse( "AP" )
  697. attrs:|DECL_ABSTRACT|DECL_PRIVATE
  698. Else If CParse( "APW" )
  699. attrs:|DECL_ABSTRACT|DECL_PRIVATE| DECL_API_WIN32
  700. Else If CParse( "AR" )
  701. attrs:|DECL_ABSTRACT|DECL_PROTECTED
  702. Else If CParse( "ARW" )
  703. attrs:|DECL_ABSTRACT|DECL_PROTECTED| DECL_API_WIN32
  704. Else If CParse( "W" )
  705. attrs:|DECL_API_WIN32
  706. Else If CParse( "O" )
  707. attrs:|FUNC_OPERATOR
  708. Else If CParse( "OW" )
  709. attrs:|FUNC_OPERATOR| DECL_API_WIN32
  710. Else If CParse( "OP" )
  711. attrs:|FUNC_OPERATOR|DECL_PRIVATE
  712. Else If CParse( "OPW" )
  713. attrs:|FUNC_OPERATOR|DECL_PRIVATE| DECL_API_WIN32
  714. Else If CParse( "OR" )
  715. attrs:|FUNC_OPERATOR|DECL_PROTECTED
  716. Else If CParse( "ORW" )
  717. attrs:|FUNC_OPERATOR|DECL_PROTECTED| DECL_API_WIN32
  718. Else If CParse( "P" )
  719. attrs:|DECL_PRIVATE
  720. Else If CParse( "PW" )
  721. attrs:|DECL_PRIVATE| DECL_API_WIN32
  722. Else If CParse( "R" )
  723. attrs:|DECL_PROTECTED
  724. Else If CParse( "RW" )
  725. attrs:|DECL_PROTECTED| DECL_API_WIN32
  726. Else If CParse( "FO" )
  727. attrs:|DECL_FINAL|FUNC_OPERATOR
  728. Else If CParse( "FOW" )
  729. attrs:|DECL_FINAL|FUNC_OPERATOR| DECL_API_WIN32
  730. Else If CParse( "FOP" )
  731. attrs:|DECL_FINAL|FUNC_OPERATOR|DECL_PRIVATE
  732. Else If CParse( "FOPW" )
  733. attrs:|DECL_FINAL|FUNC_OPERATOR|DECL_PRIVATE| DECL_API_WIN32
  734. Else If CParse( "FOR" )
  735. attrs:|DECL_FINAL|FUNC_OPERATOR|DECL_PROTECTED
  736. Else If CParse( "FORW" )
  737. attrs:|DECL_FINAL|FUNC_OPERATOR|DECL_PROTECTED| DECL_API_WIN32
  738. Else If CParse( "AO" )
  739. attrs:|DECL_ABSTRACT|FUNC_OPERATOR
  740. Else If CParse( "AOW" )
  741. attrs:|DECL_ABSTRACT|FUNC_OPERATOR| DECL_API_WIN32
  742. Else If CParse( "AOP" )
  743. attrs:|DECL_ABSTRACT|FUNC_OPERATOR|DECL_PRIVATE
  744. Else If CParse( "AOPW" )
  745. attrs:|DECL_ABSTRACT|FUNC_OPERATOR|DECL_PRIVATE| DECL_API_WIN32
  746. Else If CParse( "AOR" )
  747. attrs:|DECL_ABSTRACT|FUNC_OPERATOR|DECL_PROTECTED
  748. Else If CParse( "AORW" )
  749. attrs:|DECL_ABSTRACT|FUNC_OPERATOR|DECL_PROTECTED| DECL_API_WIN32
  750. 'Else If CParse( "property" )
  751. ' If attrs & FUNC_METHOD
  752. ' attrs:|FUNC_PROPERTY
  753. ' Else
  754. ' Err "Only methods can be properties."
  755. ' EndIf
  756. Else
  757. Exit
  758. EndIf
  759. Forever
  760. Local funcDecl:TFuncDecl
  761. If attrs & FUNC_CTOR Then
  762. funcDecl = New TNewDecl.CreateF( id,ty,args,attrs )
  763. Else
  764. If fdecl Then
  765. funcDecl = fdecl
  766. funcDecl.ident = id
  767. Else
  768. funcDecl = New TFuncDecl.CreateF( id,ty,args,attrs )
  769. End If
  770. End If
  771. funcDecl.retType = ty
  772. If CParse("&") Then
  773. funcDecl.attrs :| DECL_POINTER
  774. End If
  775. 'If funcDecl.IsExtern()
  776. If Not (funcDecl.attrs & (FUNC_PTR | FUNC_INIT)) Then
  777. ' funcDecl.munged=funcDecl.ident
  778. If CParse( "=" )
  779. If CParse("mem")
  780. If CParse(":")
  781. If CParse("p")
  782. If CParse("(") Then
  783. funcDecl.munged = ParseStringLit()
  784. Cparse(")")
  785. EndIf
  786. End If
  787. End If
  788. Else
  789. funcDecl.munged=ParseStringLit()
  790. End If
  791. End If
  792. End If
  793. ' read function cast stuff
  794. If CParse(":") Then
  795. ' ret type
  796. Local rt$=_toker._toke
  797. If CParse("unsigned") Then
  798. rt :+ " " + _toker._toke
  799. End If
  800. NextToke
  801. If CParse("*") Then
  802. rt:+ "*"
  803. If CParse("*") Then
  804. rt:+ "*"
  805. End If
  806. End If
  807. funcDecl.castTo = rt
  808. ' fname
  809. Local fn$=_toker._toke
  810. NextToke
  811. ' args
  812. Parse("(")
  813. If Not CParse(")") Then
  814. Local i:Int = 0
  815. Repeat
  816. Local at$=_toker._toke
  817. If CParse("const") Then
  818. at :+ " " + _toker._toke
  819. End If
  820. If CParse("unsigned") Then
  821. at :+ " " + _toker._toke
  822. End If
  823. NextToke
  824. If CParse("*") Then
  825. at:+ "*"
  826. If CParse("*") Then
  827. at:+ "*"
  828. End If
  829. End If
  830. ' function pointer
  831. If CParse("(") Then
  832. Parse("*")
  833. Parse(")")
  834. at :+ "(*)"
  835. Parse("(")
  836. at :+ "("
  837. While Not CParse(")")
  838. NextToke
  839. at :+ _toker._toke
  840. Wend
  841. at :+ ")"
  842. End If
  843. args[i].castTo = at
  844. If _toker._toke=")" Exit
  845. Parse ","
  846. i:+ 1
  847. Forever
  848. End If
  849. End If
  850. ' Return funcDecl
  851. 'EndIf
  852. If funcDecl.attrs & DECL_POINTER Then
  853. funcDecl.attrs :| FUNC_PTR
  854. End If
  855. 'If funcDecl.IsAbstract() Return funcDecl
  856. Return funcDecl
  857. End Method
  858. Method ParseDecl:TDecl( toke$,attrs:Int )
  859. SetErr
  860. Local pos:Int, tokeType:Int
  861. pos = _toker._tokePos
  862. tokeType = _toker._tokeType
  863. Local id$=ParseIdent()
  864. Local ty:TType
  865. Local init:TExpr
  866. If attrs & DECL_EXTERN
  867. ty=ParseDeclType(attrs)
  868. 'Else If CParse( ":=" )
  869. ' init=ParseExpr()
  870. Else
  871. ty=ParseDeclType(attrs)
  872. If CParse( "(") Then
  873. 'DebugStop
  874. ' function pointer
  875. _toker.rollback(pos, tokeType)
  876. _toker._toke = id
  877. '_toker.NextToke()
  878. Local decl:TFuncDecl = ParseFuncDecl( id, FUNC_PTR | FUNC_INIT )
  879. ty = New TFunctionPtrType
  880. TFunctionPtrType(ty).func = decl
  881. If attrs & DECL_FIELD Then
  882. decl.attrs :| FUNC_METHOD
  883. End If
  884. ' an array of function pointers?
  885. If CParse( "&" ) Then
  886. End If
  887. While IsArrayDef()
  888. ty = ParseArrayType(ty)
  889. If CParse( "&" ) Then
  890. End If
  891. Wend
  892. End If
  893. If CParse("`") Then
  894. If CParse("`") Then
  895. attrs :| DECL_PROTECTED
  896. Else
  897. attrs :| DECL_PRIVATE
  898. End If
  899. End If
  900. Rem
  901. If CParse( "=" )
  902. ' TODO init=ParseExpr()
  903. If CParse("$") Then
  904. ' string value
  905. init = ParseUnaryExpr()
  906. Else
  907. init = ParseUnaryExpr()
  908. End If
  909. 'DebugLog "TODO : ParseExpression"
  910. Else If CParse( "[" )
  911. 'Local ln:TExpr=ParseExpr()
  912. Parse "]"
  913. 'While CParse( "[]" )
  914. ' ty=New TArrayType.Create(ty)
  915. 'Wend
  916. 'init=New TNewArrayExpr.Create( ty,ln)
  917. 'ty=New TArrayType.Create( ty )
  918. Else If toke<>"const"
  919. init=New TConstExpr.Create( ty,"" )
  920. Else
  921. Err "Constants must be initialized."
  922. EndIf
  923. End Rem
  924. EndIf
  925. Local decl:TValDecl
  926. If attrs & DECL_GLOBAL
  927. decl=New TGlobalDecl.Create( id,ty,init,attrs )
  928. Else If attrs & DECL_FIELD
  929. decl=New TFieldDecl.Create( id,ty,init,attrs )
  930. Else If attrs & DECL_CONST
  931. decl=New TConstDecl.Create( id,ty,init,attrs )
  932. Else If attrs & DECL_LOCAL
  933. decl=New TLocalDecl.Create( id,ty,init,attrs )
  934. EndIf
  935. 'DebugStop
  936. ' If decl.IsExtern()
  937. If CParse( "=" )
  938. If CParse("mem")
  939. ' Change to global
  940. ' Until this point, it was "probably" a const, but now we know for sure
  941. ' that it must be a global.
  942. If attrs & DECL_CONST Then
  943. attrs :| DECL_GLOBAL
  944. attrs :~ DECL_CONST
  945. decl=New TGlobalDecl.Create( id,ty,init,attrs )
  946. End If
  947. If CParse(":")
  948. If CParse("p")
  949. If CParse("(") Then
  950. decl.munged = ParseStringLit()
  951. ' for function pointers, ensure actual function reference is set too.
  952. If TFunctionPtrType(decl.declTy) Then
  953. TFunctionPtrType(decl.declTy).func.munged = decl.munged
  954. End If
  955. Parse(")")
  956. EndIf
  957. End If
  958. Else
  959. If CParse("(") Then
  960. decl.munged = ParseStringLit()
  961. Parse(")")
  962. EndIf
  963. End If
  964. Else
  965. If TStringType(ty)
  966. If CParse("$") Then
  967. decl.declInit = ParseUnaryExpr()
  968. End If
  969. Else
  970. ' a default value ?
  971. decl.declInit = ParseUnaryExpr()
  972. End If
  973. End If
  974. Else
  975. decl.munged=decl.ident
  976. EndIf
  977. ' EndIf
  978. Return decl
  979. End Method
  980. ' replaces While CParse( "[]" ) sections, with support for multi-dimension arrays
  981. Method ParseArrayType:TType(ty:TType)
  982. While True
  983. Local dims:Int = 1
  984. If CParse("[]") Then
  985. ty=New TArrayType.Create( ty )
  986. Exit
  987. End If
  988. If Not CParse("[") Then
  989. Exit
  990. End If
  991. While CParse( ",")
  992. dims :+ 1
  993. Wend
  994. Parse "]"
  995. ty=New TArrayType.Create( ty, dims )
  996. Exit
  997. Wend
  998. Return ty
  999. End Method
  1000. Method IsArrayDef:Int()
  1001. Local isDef:Int = True
  1002. Local toker:TToker=New TToker.Copy(_toker)
  1003. While True
  1004. If CParseToker(toker, "[]") Then
  1005. Exit
  1006. End If
  1007. If Not CParseToker(toker, "[") Then
  1008. isDef = False
  1009. Exit
  1010. End If
  1011. While CParseToker(toker, ",")
  1012. Wend
  1013. If Not CParseToker(toker, "]") Then
  1014. isDef = False
  1015. Exit
  1016. End If
  1017. Exit
  1018. Wend
  1019. Return isDef
  1020. End Method
  1021. Method ParseDeclType:TType(attrs:Int Var, fn:Int = False)
  1022. Local ty:TType
  1023. Select _toker._toke
  1024. 'Case "?"
  1025. ' NextToke
  1026. ' ty=TType.boolType
  1027. Case "%"
  1028. NextToke
  1029. ty=New TIntType
  1030. If CParse("%") Then
  1031. ty = New TLongType
  1032. ElseIf CParse("z") Then
  1033. ty = New TSizetType
  1034. ElseIf CParse("j") Then
  1035. ty = New TInt128Type
  1036. ElseIf CParse("w") Then
  1037. ty = New TWParamType
  1038. ElseIf CParse("x") Then
  1039. ty = New TLParamType
  1040. End If
  1041. If CParse("&") And Not (attrs & DECL_FIELD) Then
  1042. attrs :| DECL_GLOBAL
  1043. attrs :~ DECL_CONST
  1044. End If
  1045. ' pointer
  1046. While CParse( "*" )
  1047. ty = TType.MapToPointerType(ty)
  1048. Wend
  1049. Case "|"
  1050. NextToke
  1051. ty=New TUIntType
  1052. If CParse("|") Then
  1053. ty = New TULongType
  1054. End If
  1055. If CParse("&") And Not (attrs & DECL_FIELD) Then
  1056. attrs :| DECL_GLOBAL
  1057. attrs :~ DECL_CONST
  1058. End If
  1059. ' pointer
  1060. While CParse( "*" )
  1061. ty = TType.MapToPointerType(ty)
  1062. Wend
  1063. Case "#"
  1064. NextToke
  1065. ty=New TFloatType
  1066. If CParse("&") And Not (attrs & DECL_FIELD) Then
  1067. attrs :| DECL_GLOBAL
  1068. attrs :~ DECL_CONST
  1069. End If
  1070. ' pointer
  1071. While CParse( "*" )
  1072. ty = TType.MapToPointerType(ty)
  1073. Wend
  1074. Case "$"
  1075. NextToke
  1076. ty=New TStringType
  1077. If CParse("z") Then
  1078. ty._flags :| TType.T_CHAR_PTR
  1079. Else If CParse("w") Then
  1080. ty._flags :| TType.T_SHORT_PTR
  1081. End If
  1082. If CParse( "&" ) And Not (attrs & DECL_FIELD)
  1083. attrs :| DECL_GLOBAL
  1084. attrs :~ DECL_CONST
  1085. End If
  1086. Case "!"
  1087. NextToke
  1088. ty=New TDoubleType
  1089. If CParse("k") Then
  1090. ty = New TFloat128Type
  1091. Else If CParse("m") Then
  1092. ty = New TDouble128Type
  1093. Else If CParse("h") Then
  1094. ty = New TFloat64Type
  1095. End If
  1096. If CParse("&") And Not (attrs & DECL_FIELD) Then
  1097. attrs :| DECL_GLOBAL
  1098. attrs :~ DECL_CONST
  1099. End If
  1100. ' pointer
  1101. While CParse( "*" )
  1102. ty = TType.MapToPointerType(ty)
  1103. Wend
  1104. Case ":"
  1105. NextToke
  1106. ty=ParseNewType()
  1107. If CParse("*") Then
  1108. If TIdentType(ty) Then
  1109. ty = TType.MapToPointerType(ty)
  1110. While CParse( "*" )
  1111. ty = TType.MapToPointerType(ty)
  1112. Wend
  1113. End If
  1114. End If
  1115. CParse("&")
  1116. Case "?"
  1117. NextToke
  1118. attrs :| DECL_EXTERN
  1119. If CParse("?") Then
  1120. attrs :| CLASS_INTERFACE
  1121. End If
  1122. ty=ParseNewType()
  1123. If CParse("*") Then
  1124. If TIdentType(ty) Then
  1125. ty = TType.MapToPointerType(ty)
  1126. While CParse( "*" )
  1127. ty = TType.MapToPointerType(ty)
  1128. Wend
  1129. End If
  1130. End If
  1131. CParse("&")
  1132. Case "~~"
  1133. NextToke
  1134. attrs :| DECL_EXTERN | CLASS_STRUCT
  1135. ty=ParseNewType()
  1136. If CParse("*") Then
  1137. If TIdentType(ty) Then
  1138. ty = TType.MapToPointerType(ty)
  1139. While CParse( "*" )
  1140. ty = TType.MapToPointerType(ty)
  1141. Wend
  1142. End If
  1143. End If
  1144. CParse("&")
  1145. Case "@"
  1146. NextToke
  1147. ty=New TByteType
  1148. If CParse("@") Then
  1149. ty = New TShortType
  1150. End If
  1151. If CParse( "&" )
  1152. 'DebugStop
  1153. End If
  1154. ' pointer
  1155. While CParse( "*" )
  1156. ty = TType.MapToPointerType(ty)
  1157. Wend
  1158. ' TODO
  1159. ' Case "!" ' BaH Double
  1160. ' NextToke
  1161. ' ty=TType.doubleType
  1162. Default
  1163. 'If _module.IsStrict() Err "Illegal type expression."
  1164. 'DebugStop
  1165. If Not fn Then
  1166. ty=New TIntType
  1167. End If
  1168. End Select
  1169. If CParse( "&" ) Then
  1170. End If
  1171. While IsArrayDef()
  1172. ty = ParseArrayType(ty)
  1173. If CParse( "&" ) Then
  1174. End If
  1175. Wend
  1176. If CParse( "&" ) Then
  1177. End If
  1178. Return ty
  1179. End Method
  1180. Method ParseNewType:TType()
  1181. If CParse( "byte" ) Or CParse( "@" )
  1182. Local ty:TType = New TByteType
  1183. While CParse("ptr")
  1184. ty = TType.MapToPointerType(ty)
  1185. Wend
  1186. While CParse( "*" )
  1187. ty = TType.MapToPointerType(ty)
  1188. Wend
  1189. Return ty
  1190. End If
  1191. If CParse( "short" )
  1192. Local ty:TType = New TShortType
  1193. While CParse("ptr")
  1194. ty = TType.MapToPointerType(ty)
  1195. Wend
  1196. While CParse( "*" )
  1197. ty = TType.MapToPointerType(ty)
  1198. Wend
  1199. Return ty
  1200. End If
  1201. If CParse( "int" ) Or CParse( "%" )
  1202. Local ty:TType = New TIntType
  1203. While CParse("ptr")
  1204. ty = TType.MapToPointerType(ty)
  1205. Wend
  1206. While CParse( "*" )
  1207. ty = TType.MapToPointerType(ty)
  1208. Wend
  1209. Return ty
  1210. End If
  1211. If CParse( "uint" ) Or CParse( "|" )
  1212. Local ty:TType = New TUIntType
  1213. While CParse("ptr")
  1214. ty = TType.MapToPointerType(ty)
  1215. Wend
  1216. While CParse( "*" )
  1217. ty = TType.MapToPointerType(ty)
  1218. Wend
  1219. Return ty
  1220. End If
  1221. If CParse( "float" )
  1222. Local ty:TType = New TFloatType
  1223. While CParse("ptr")
  1224. ty = TType.MapToPointerType(ty)
  1225. Wend
  1226. While CParse( "*" )
  1227. ty = TType.MapToPointerType(ty)
  1228. Wend
  1229. Return ty
  1230. End If
  1231. If CParse( "string" ) Return New TStringType
  1232. If CParse( "object" ) Return New TIdentType.Create( "brl.classes.object" )
  1233. If CParse( "long" )
  1234. Local ty:TType = New TLongType
  1235. While CParse("ptr")
  1236. ty = TType.MapToPointerType(ty)
  1237. Wend
  1238. While CParse( "*" )
  1239. ty = TType.MapToPointerType(ty)
  1240. Wend
  1241. Return ty
  1242. End If
  1243. If CParse( "ulong" )
  1244. Local ty:TType = New TULongType
  1245. While CParse("ptr")
  1246. ty = TType.MapToPointerType(ty)
  1247. Wend
  1248. While CParse( "*" )
  1249. ty = TType.MapToPointerType(ty)
  1250. Wend
  1251. Return ty
  1252. End If
  1253. If CParse( "double" )
  1254. Local ty:TType = New TDoubleType
  1255. While CParse("ptr")
  1256. ty = TType.MapToPointerType(ty)
  1257. Wend
  1258. While CParse( "*" )
  1259. ty = TType.MapToPointerType(ty)
  1260. Wend
  1261. Return ty
  1262. End If
  1263. If CParse( "size_t" )
  1264. Local ty:TType = New TSizeTType
  1265. While CParse("ptr")
  1266. ty = TType.MapToPointerType(ty)
  1267. Wend
  1268. While CParse( "*" )
  1269. ty = TType.MapToPointerType(ty)
  1270. Wend
  1271. Return ty
  1272. End If
  1273. If CParse( "int128" )
  1274. Local ty:TType = New TInt128Type
  1275. While CParse("ptr")
  1276. ty = TType.MapToPointerType(ty)
  1277. Wend
  1278. While CParse( "*" )
  1279. ty = TType.MapToPointerType(ty)
  1280. Wend
  1281. Return ty
  1282. End If
  1283. If CParse( "float64" )
  1284. Local ty:TType = New TFloat64Type
  1285. While CParse("ptr")
  1286. ty = TType.MapToPointerType(ty)
  1287. Wend
  1288. While CParse( "*" )
  1289. ty = TType.MapToPointerType(ty)
  1290. Wend
  1291. Return ty
  1292. End If
  1293. If CParse( "float128" )
  1294. Local ty:TType = New TFloat128Type
  1295. While CParse("ptr")
  1296. ty = TType.MapToPointerType(ty)
  1297. Wend
  1298. While CParse( "*" )
  1299. ty = TType.MapToPointerType(ty)
  1300. Wend
  1301. Return ty
  1302. End If
  1303. If CParse( "double128" )
  1304. Local ty:TType = New TDouble128Type
  1305. While CParse("ptr")
  1306. ty = TType.MapToPointerType(ty)
  1307. Wend
  1308. While CParse( "*" )
  1309. ty = TType.MapToPointerType(ty)
  1310. Wend
  1311. Return ty
  1312. End If
  1313. If CParse( "wparam" )
  1314. Local ty:TType = New TWParamType
  1315. While CParse("ptr")
  1316. ty = TType.MapToPointerType(ty)
  1317. Wend
  1318. While CParse( "*" )
  1319. ty = TType.MapToPointerType(ty)
  1320. Wend
  1321. Return ty
  1322. End If
  1323. If CParse( "lparam" )
  1324. Local ty:TType = New TLParamType
  1325. While CParse("ptr")
  1326. ty = TType.MapToPointerType(ty)
  1327. Wend
  1328. While CParse( "*" )
  1329. ty = TType.MapToPointerType(ty)
  1330. Wend
  1331. Return ty
  1332. End If
  1333. Return ParseIdentType()
  1334. End Method
  1335. Method ApplyFunctionAttributes(classDecl:TClassDecl, attrs:Int)
  1336. For Local decl:TFuncDecl = EachIn classDecl._decls
  1337. decl.attrs :| attrs
  1338. Next
  1339. End Method
  1340. Method SetErr()
  1341. If _toker.Path()
  1342. _errInfo=FormatError(_toker.Path(), _toker.Line(), 0)
  1343. EndIf
  1344. End Method
  1345. End Type