decl.bmx 78 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257
  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. Const DECL_EXTERN:Int= $010000
  25. Const DECL_PRIVATE:Int= $020000
  26. Const DECL_ABSTRACT:Int= $040000
  27. Const DECL_FINAL:Int= $080000
  28. Const DECL_SEMANTED:Int= $100000
  29. Const DECL_SEMANTING:Int= $200000
  30. Const DECL_POINTER:Int= $400000
  31. Const DECL_ARG:Int= $800000
  32. Const DECL_INITONLY:Int= $1000000
  33. Const DECL_NODEBUG:Int= $2000000
  34. Const DECL_PROTECTED:Int= $4000000
  35. Const DECL_API_WIN32:Int= $10000000
  36. Const DECL_API_OS:Int=DECL_API_WIN32
  37. Const CLASS_INTERFACE:Int= $001000
  38. Const CLASS_THROWABLE:Int= $002000
  39. Const CLASS_STRUCT:Int= $004000
  40. Const SCOPE_FUNC:Int = 0
  41. Const SCOPE_CLASS_LOCAL:Int = 1
  42. Const SCOPE_CLASS_HEIRARCHY:Int = 2
  43. Const SCOPE_MODULE:Int = 3
  44. Const SCOPE_ALL:Int = 4
  45. Global _env:TScopeDecl
  46. Global _envStack:TList=New TList
  47. Global _appInstance:TAppDecl
  48. Global _loopnest:Int
  49. Function PushEnv( env:TScopeDecl )
  50. If _env _envStack.AddLast( _env )
  51. _env=env
  52. End Function
  53. Function PopEnv()
  54. _env=TScopeDecl( _envStack.RemoveLast() )
  55. End Function
  56. Type TFuncDeclList Extends TList
  57. Field ident:String
  58. Field _identLower:String
  59. Method IdentLower:String()
  60. If Not _identLower Then
  61. _identLower = ident.ToLower()
  62. End If
  63. Return _identLower
  64. End Method
  65. End Type
  66. Type TMetadata
  67. Field metadataString:String
  68. ' key/value pairs
  69. Field meta:TMap
  70. Method InsertMeta(key:String, value:String)
  71. If Not meta Then
  72. meta = New TMap
  73. End If
  74. meta.Insert(key, value)
  75. End Method
  76. Method HasMeta:Int(key:String)
  77. Return meta And meta.Contains(key.ToLower())
  78. End Method
  79. End Type
  80. Type TDecl
  81. Field ident$
  82. Field munged$
  83. Field errInfo$
  84. Field actual:TDecl
  85. Field scope:TScopeDecl
  86. Field attrs:Int
  87. Field metadata:TMetadata = New TMetadata
  88. Field declImported:Int = False
  89. Field generated:Int
  90. Field _identLower:String
  91. Method New()
  92. errInfo=_errInfo
  93. actual=Self
  94. End Method
  95. Method OnCopy:TDecl(deep:Int = True) Abstract
  96. Method IdentLower:String()
  97. If Not _identLower Then
  98. _identLower = ident.ToLower()
  99. End If
  100. Return _identLower
  101. End Method
  102. Method ToString$()
  103. If TClassDecl( scope ) Return scope.ToString()+"."+ident
  104. Return ident
  105. End Method
  106. Method ToTypeString:String()
  107. End Method
  108. Method IsExtern:Int()
  109. Return (attrs & DECL_EXTERN)<>0
  110. End Method
  111. Method IsPrivate:Int()
  112. Return (attrs & DECL_PRIVATE)<>0
  113. End Method
  114. Method IsProtected:Int()
  115. Return (attrs & DECL_PROTECTED)<>0
  116. End Method
  117. Method IsPublic:Int()
  118. Return Not (IsPrivate() Or IsProtected())
  119. End Method
  120. Method IsAbstract:Int()
  121. Return (attrs & DECL_ABSTRACT)<>0
  122. End Method
  123. Method IsSemanted:Int()
  124. Return (attrs & DECL_SEMANTED)<>0
  125. End Method
  126. Method IsSemanting:Int()
  127. Return (attrs & DECL_SEMANTING)<>0
  128. End Method
  129. Method IsNoDebug:Int()
  130. Return (attrs & DECL_NODEBUG)<>0
  131. End Method
  132. Method FuncScope:TFuncDecl()
  133. If TFuncDecl( Self ) Return TFuncDecl( Self )
  134. If scope Return scope.FuncScope()
  135. End Method
  136. Method ClassScope:TClassDecl()
  137. If TClassDecl( Self ) Return TClassDecl( Self )
  138. If scope Return scope.ClassScope()
  139. End Method
  140. Method ModuleScope:TModuleDecl()
  141. If TModuleDecl( Self ) Return TModuleDecl( Self )
  142. ' "app" is a module container
  143. If TAppDecl( Self ) Return TAppDecl( Self).mainModule
  144. If scope Return scope.ModuleScope()
  145. End Method
  146. Method AppScope:TAppDecl()
  147. If TAppDecl( Self ) Return TAppDecl( Self )
  148. If scope Return scope.AppScope()
  149. End Method
  150. Method CheckAccess:Int()
  151. If IsPrivate() And ModuleScope()<>_env.ModuleScope() Return False
  152. Return True
  153. End Method
  154. Method AssertAccess()
  155. If Not CheckAccess()
  156. If IsPrivate() Then
  157. Err ToString() +" is private."
  158. Else
  159. Err ToString() +" is protected."
  160. End If
  161. EndIf
  162. End Method
  163. Method Copy:TDecl(deep:Int = True)
  164. Local t:TDecl=OnCopy(deep)
  165. t.munged=munged
  166. t.errInfo=errInfo
  167. Return t
  168. End Method
  169. Method Semant()
  170. If IsSemanted() Return
  171. If IsSemanting() Err "Cyclic declaration of '"+ident+"'."
  172. If actual<>Self
  173. actual.Semant
  174. EndIf
  175. PushErr errInfo
  176. If scope
  177. PushEnv scope
  178. EndIf
  179. attrs:|DECL_SEMANTING
  180. 'If ident And ClassScope() Print "Semanting "+ToString()
  181. OnSemant
  182. attrs:&~DECL_SEMANTING
  183. attrs:|DECL_SEMANTED
  184. If scope
  185. 'If Not IsExtern()
  186. If TFuncDecl(Self) And attrs & FUNC_PTR
  187. 'DebugLog "**** " + ident
  188. Else
  189. scope._semanted.AddLast Self
  190. If TGlobalDecl( Self )
  191. ' FIXME
  192. If AppScope() Then
  193. AppScope().semantedGlobals.AddLast TGlobalDecl( Self )
  194. End If
  195. EndIf
  196. If TModuleDecl( scope )
  197. 'DebugStop
  198. ' FIXME
  199. Local app:TAppDecl = AppScope()
  200. If app Then
  201. app._semanted.AddLast Self
  202. End If
  203. EndIf
  204. EndIf
  205. If TValDecl(Self) And TValDecl(Self).deferInit Then
  206. TValDecl(Self).SemantInit
  207. End If
  208. PopEnv
  209. Else
  210. If TValDecl(Self) And TValDecl(Self).deferInit Then
  211. TValDecl(Self).SemantInit
  212. End If
  213. EndIf
  214. PopErr
  215. End Method
  216. Method InitInstance:TDecl( decl:TDecl )
  217. decl.ident=ident
  218. decl.munged=munged
  219. decl.errInfo=errInfo
  220. decl.actual=actual
  221. decl.scope=Null
  222. decl.attrs=attrs & ~(DECL_SEMANTED|DECL_SEMANTING)
  223. Return decl
  224. End Method
  225. Method GenInstance:TDecl()
  226. InternalErr
  227. End Method
  228. Method OnSemant() Abstract
  229. End Type
  230. Type TValDecl Extends TDecl
  231. 'pre-semant
  232. Field declTy:TType
  233. Field declInit:TExpr
  234. 'post-semant
  235. Field ty:TType
  236. Field init:TExpr
  237. Field deferInit:Int = False
  238. Method ToString$()
  239. Local t$=Super.ToString()
  240. If ty Return t+":"+ty.ToString()
  241. If declTy Return t+":"+declTy.ToString()
  242. Return t+":?"
  243. End Method
  244. Method ToTypeString:String()
  245. If ty Return ty.ToString()
  246. If declTy Return declTy.ToString()
  247. End Method
  248. Method CopyInit:TExpr()
  249. If init Return init.Copy()
  250. End Method
  251. Method OnSemant()
  252. If declTy
  253. ' ensure to set the scope for a function pointer array before semanting
  254. If TArrayType(declTy) And TFunctionPtrType(TArrayType(declTy).elemType) Then
  255. If Not TFunctionPtrType(TArrayType(declTy).elemType).func.scope Then
  256. If scope Then
  257. TFunctionPtrType(TArrayType(declTy).elemType).func.scope = scope
  258. Else
  259. TFunctionPtrType(TArrayType(declTy).elemType).func.scope = _env
  260. End If
  261. End If
  262. End If
  263. ' pass the scope into the function ptr
  264. If TFunctionPtrType(declTy) Then
  265. If Not TFunctionPtrType(declTy).func.scope Then
  266. If scope Then
  267. TFunctionPtrType(declTy).func.scope = scope
  268. Else
  269. TFunctionPtrType(declTy).func.scope = _env
  270. End If
  271. End If
  272. End If
  273. ty=declTy.Semant()
  274. If Not deferInit Then
  275. SemantInit()
  276. End If
  277. Else If declInit
  278. If Not deferInit Then
  279. SemantInit()
  280. End If
  281. Else
  282. InternalErr
  283. EndIf
  284. End Method
  285. Method SemantInit()
  286. ' for field initialisation, create a stub New() method to use as current scope
  287. ' since fields are initialised in New(). Otherwise the scope would be "class", which is
  288. ' incorrect for processing field inits.
  289. If TFieldDecl(Self) And declInit Then
  290. Local newScope:TFuncDecl = New TFuncDecl.CreateF( "new", Null,Null,FUNC_METHOD )
  291. newScope.scope = _env
  292. PushEnv(newScope)
  293. End If
  294. If declTy
  295. If declInit Then
  296. If TFunctionPtrType(ty) Then
  297. Local expr:TExpr
  298. If TInvokeExpr(declInit) Then
  299. expr = declInit.Copy()
  300. Else If TConstExpr(declInit) Then
  301. expr = declInit.Copy().Semant()
  302. Else If TFuncCallExpr(declInit) Then
  303. expr=declInit.Copy().Semant()
  304. Else If TNullExpr(declInit) Then
  305. expr = declInit
  306. Else
  307. ' declInit can only be an expression, never a statement
  308. ' this means that any function call in there is required to have parentheses, and will
  309. ' thus appear in the form of a TFuncCallExpr
  310. ' as such, trying SemantFunc in the Else branch seems pointless and will in fact wrongly
  311. ' interpret function pointers (as TIdentExpr, TIndexExpr, possibly others?) as calls
  312. Rem
  313. Local argExpr:TExpr[] = New TExpr[0]
  314. For Local arg:TArgDecl = EachIn TFunctionPtrType(ty).func.argDecls
  315. Local ldecl:TLocalDecl = New TLocalDecl.Create(arg.ident, arg.declTy, Null, 0)
  316. ldecl.Semant()
  317. Local aexp:TVarExpr = New TVarExpr.Create(ldecl)
  318. 'Local aexp:TIdentTypeExpr = New TIdentTypeExpr.Create(arg.declTy)
  319. aexp.Semant()
  320. argExpr :+ [aexp]
  321. Next
  322. expr=declInit.Copy().SemantFunc(argExpr, False, False)
  323. If Not expr Then
  324. expr = declInit.Copy().Semant()
  325. End If
  326. End Rem
  327. expr = declInit.Copy().Semant()
  328. End If
  329. If expr.exprType.EqualsType( ty ) Then
  330. init = expr
  331. Else
  332. init = New TCastExpr.Create( ty,expr,CAST_EXPLICIT ).Semant()
  333. End If
  334. Else
  335. If TArrayExpr(declInit) And TArrayType(ty) And TNumericType(TArrayType(ty).elemType) Then
  336. TArrayExpr(declInit).toType = TArrayType(ty).elemType
  337. End If
  338. init=declInit.Copy().SemantAndCast(ty)
  339. End If
  340. End If
  341. Else If declInit
  342. init=declInit.Copy().Semant()
  343. ty=init.exprType
  344. End If
  345. If init Then
  346. If TVarExpr(init) And TVarExpr(init).decl = Self Then
  347. Err "Identifier '" + TVarExpr(init).decl.ident + "' not found."
  348. End If
  349. If TNewObjectExpr(init) And TVarExpr(TNewObjectExpr(init).instanceExpr) And TVarExpr(TNewObjectExpr(init).instanceExpr).decl = Self Then
  350. Err "Identifier '" + Self.ident + "' not found."
  351. End If
  352. End If
  353. ' remove the temporary scope
  354. If TFieldDecl(Self) And declInit Then
  355. PopEnv()
  356. End If
  357. End Method
  358. End Type
  359. Type TConstDecl Extends TValDecl
  360. Field value$
  361. Method Create:TConstDecl( ident$,ty:TType,init:TExpr,attrs:Int )
  362. Self.ident=ident
  363. Self.munged=ident
  364. Self.declTy=ty
  365. Self.declInit=init
  366. Self.attrs=attrs
  367. Return Self
  368. End Method
  369. Method GenInstance:TDecl()
  370. Local inst:TConstDecl = New TConstDecl
  371. InitInstance inst
  372. inst.declTy=declTy
  373. inst.declInit=declInit
  374. Return inst
  375. End Method
  376. Method OnCopy:TDecl(deep:Int = True)
  377. Return New TConstDecl.Create( ident,ty,CopyInit(), attrs )
  378. End Method
  379. Method OnSemant()
  380. Super.OnSemant()
  381. 'If Not IsExtern() value=init.Eval()
  382. If init Then
  383. value=init.Eval()
  384. If TStringType(ty) And Not _appInstance.hasStringConst(value) Then
  385. _appInstance.mapStringConsts(value)
  386. End If
  387. End If
  388. End Method
  389. Method ToString$()
  390. Return "Const "+Super.ToString()
  391. End Method
  392. End Type
  393. Type TVarDecl Extends TValDecl
  394. End Type
  395. Type TLocalDecl Extends TVarDecl
  396. Field done:Int
  397. Field volatile:Int = True
  398. Method Create:TLocalDecl( ident$,ty:TType,init:TExpr,attrs:Int=0, generated:Int = False, volatile:Int = True )
  399. Self.ident=ident
  400. Self.declTy=ty
  401. Self.declInit=init
  402. Self.attrs=attrs
  403. Self.generated=generated
  404. Self.volatile=volatile
  405. Return Self
  406. End Method
  407. Method OnCopy:TDecl(deep:Int = True)
  408. Return New TLocalDecl.Create( ident,ty,CopyInit(),attrs, generated, volatile )
  409. End Method
  410. Method GetDeclPrefix:String()
  411. Return "Local "
  412. End Method
  413. Method ToString$()
  414. Return GetDeclPrefix() + Super.ToString()
  415. End Method
  416. End Type
  417. Type TArgDecl Extends TLocalDecl
  418. Field castTo:String
  419. Method Create:TArgDecl( ident$,ty:TType,init:TExpr,attrs:Int=0, generated:Int = False, volatile:Int = True )
  420. Self.ident=ident
  421. Self.declTy=ty
  422. Self.declInit=init
  423. Self.attrs=attrs
  424. Self.generated=generated
  425. Self.volatile=volatile
  426. Return Self
  427. End Method
  428. Method GenInstance:TDecl()
  429. Local inst:TArgDecl=New TArgDecl
  430. InitInstance inst
  431. inst.declTy=declTy
  432. inst.declInit=declInit
  433. Return inst
  434. End Method
  435. Method OnCopy:TDecl(deep:Int = True)
  436. Local d:TArgDecl = New TArgDecl.Create( ident,ty,CopyInit(),attrs,generated,volatile )
  437. d.ty = d.declTy
  438. d.init = d.declInit
  439. Return d
  440. End Method
  441. Method GetDeclPrefix:String()
  442. Return ""
  443. End Method
  444. Method ToString$()
  445. Return Super.ToString()
  446. End Method
  447. End Type
  448. Type TGlobalDecl Extends TVarDecl
  449. Field inited:Int
  450. Field funcGlobal:Int
  451. Method Create:TGlobalDecl( ident$,ty:TType,init:TExpr,attrs:Int=0,funcGlobal:Int=False )
  452. Self.deferInit = True
  453. Self.ident=ident
  454. Self.declTy=ty
  455. Self.declInit=init
  456. Self.attrs=attrs
  457. Self.funcGlobal=funcGlobal
  458. Return Self
  459. End Method
  460. Method OnCopy:TDecl(deep:Int = True)
  461. Return New TGlobalDecl.Create( ident,ty,CopyInit(),attrs,funcGlobal )
  462. End Method
  463. Method ToString$()
  464. Return "Global "+Super.ToString()
  465. End Method
  466. Method GenInstance:TDecl()
  467. ' PushErr errInfo
  468. ' Err "Global variables cannot be used inside generic classes."
  469. Local inst:TGlobalDecl=New TGlobalDecl
  470. InitInstance inst
  471. inst.declTy=declTy
  472. inst.declInit=declInit
  473. Return inst
  474. End Method
  475. Method CheckAccess:Int()
  476. Local cd:TClassDecl = ClassScope()
  477. If cd Then
  478. If IsPrivate() And cd<>_env.ClassScope() Return False
  479. If IsProtected() Then
  480. Local ec:TClassDecl = _env.ClassScope()
  481. If Not ec Return False
  482. If Not ec.ExtendsClass(cd) Return False
  483. End If
  484. Return True
  485. End If
  486. Return Super.CheckAccess()
  487. End Method
  488. End Type
  489. Type TFieldDecl Extends TVarDecl
  490. ' location offset in object variable data
  491. Field offset:Int
  492. Method Create:TFieldDecl( ident$,ty:TType,init:TExpr,attrs:Int=0 )
  493. Self.ident=ident
  494. Self.declTy=ty
  495. Self.declInit=init
  496. Self.attrs=attrs
  497. Return Self
  498. End Method
  499. Method OnCopy:TDecl(deep:Int = True)
  500. Local f:TFieldDecl = New TFieldDecl.Create( ident,ty,CopyInit(),attrs )
  501. f.metadata = metadata
  502. Return f
  503. End Method
  504. Method ToString$()
  505. Return "Field "+Super.ToString()
  506. End Method
  507. Method GenInstance:TDecl()
  508. Local inst:TFieldDecl=New TFieldDecl
  509. InitInstance inst
  510. inst.declTy=declTy
  511. inst.declInit=declInit
  512. Return inst
  513. End Method
  514. Method CheckAccess:Int()
  515. If IsPrivate() And ClassScope()<>_env.ClassScope() Return False
  516. If IsProtected() And ClassScope() Then
  517. Local ec:TClassDecl = _env.ClassScope()
  518. If Not ec Return False
  519. If Not ec.ExtendsClass(ClassScope()) Return False
  520. End If
  521. Return True
  522. End Method
  523. End Type
  524. Type TAliasDecl Extends TDecl
  525. Field decl:Object
  526. Method Create:TAliasDecl( ident$,decl:Object,attrs:Int=0 )
  527. Self.ident=ident
  528. Self.decl=decl
  529. Self.attrs=attrs
  530. Return Self
  531. End Method
  532. Method OnCopy:TDecl(deep:Int = True)
  533. Return New TAliasDecl.Create( ident,decl,attrs )
  534. End Method
  535. Method OnSemant()
  536. End Method
  537. End Type
  538. Type TScopeDecl Extends TDecl
  539. 'Private
  540. Field _decls:TList=New TList'<TDecl>
  541. Field _semanted:TList=New TList'<TDecl>
  542. Field declsMap:TMap=New TMap'<Object>
  543. 'Public
  544. Method OnCopy:TDecl(deep:Int = True)
  545. InternalErr
  546. End Method
  547. Method Decls:TList()
  548. Return _decls
  549. End Method
  550. Method Semanted:TList()
  551. Return _semanted
  552. End Method
  553. Method FuncDecls:TList( id$="" )
  554. Local fdecls:TList=New TList
  555. For Local decl:TDecl=EachIn _decls
  556. If id And decl.ident<>id Continue
  557. Local fdecl:TFuncDecl=TFuncDecl( decl )
  558. If fdecl fdecls.AddLast fdecl
  559. Next
  560. Return fdecls
  561. End Method
  562. Method MethodDecls:TList( id$="" )
  563. Local fdecls:TList=New TList
  564. For Local decl:TDecl=EachIn _decls
  565. If id And decl.ident<>id Continue
  566. Local fdecl:TFuncDecl=TFuncDecl( decl )
  567. If fdecl And fdecl.IsMethod() fdecls.AddLast fdecl
  568. Next
  569. Return fdecls
  570. End Method
  571. Method SemantedFuncs:TList( id$="" )
  572. Local fdecls:TList=New TList
  573. For Local decl:TDecl=EachIn _semanted
  574. If id And decl.ident<>id Continue
  575. Local fdecl:TFuncDecl=TFuncDecl( decl )
  576. If fdecl fdecls.AddLast fdecl
  577. Next
  578. Return fdecls
  579. End Method
  580. Method SemantedMethods:TList( id$="" )
  581. Local fdecls:TList=New TList
  582. For Local decl:TDecl=EachIn _decls
  583. If id And decl.ident<>id Continue
  584. Local fdecl:TFuncDecl=TFuncDecl( decl )
  585. If fdecl And fdecl.IsMethod()
  586. If Not fdecl.IsSemanted() Then
  587. fdecl.Semant()
  588. End If
  589. fdecls.AddLast fdecl
  590. End If
  591. Next
  592. Return fdecls
  593. End Method
  594. Method InsertDecl( decl:TDecl )
  595. If decl.scope And Not (decl.attrs & DECL_INITONLY) InternalErr
  596. 'Local ident$=decl.ident
  597. If Not decl.ident Return
  598. If Not decl.scope Then
  599. decl.scope=Self
  600. End If
  601. _decls.AddLast decl
  602. 'Local _decls:TMap
  603. Local tdecl_:Object=declsMap.ValueForKey( decl.IdentLower() )
  604. If TFuncDecl( decl )
  605. Local funcs:TFuncDeclList=TFuncDeclList( tdecl_ )
  606. If funcs Or Not tdecl_
  607. If Not funcs
  608. funcs=New TFuncDeclList
  609. funcs.ident = decl.IdentLower()
  610. declsMap.Insert decl.IdentLower(),funcs
  611. EndIf
  612. funcs.AddLast TFuncDecl( decl )
  613. Return
  614. Else
  615. Err "Duplicate identifier '"+decl.ident+"'."
  616. EndIf
  617. Else If Not tdecl_
  618. declsMap.Insert decl.IdentLower(),decl
  619. Else
  620. Err "Duplicate identifier '"+decl.ident+"'."
  621. EndIf
  622. End Method
  623. Method InsertDecls( _decls:TList )
  624. For Local decl:TDecl=EachIn _decls
  625. InsertDecl decl
  626. Next
  627. End Method
  628. 'This is overridden by TClassDecl and TModuleDecl
  629. Method GetDecl:Object( ident$ )
  630. 'DebugLog "GetDecl (" + Self.ident + ") : " + ident
  631. Local decl:Object=Object(declsMap.ValueForKey( ident ))
  632. If Not decl Then
  633. If Self.IdentLower() = ident Then
  634. ' name matches but we are a "module", but not a *real* module..
  635. ' .. so we can't be looking for ourself
  636. If TModuleDecl(Self) And Self.ident.Find(".") = - 1 Then
  637. decl = Null
  638. Else
  639. decl = Self
  640. End If
  641. End If
  642. End If
  643. If Not decl Return Null
  644. Local adecl:TAliasDecl=TAliasDecl( decl )
  645. If Not adecl Return decl
  646. If adecl.CheckAccess() Return adecl.decl
  647. End Method
  648. Method FindDecl:Object( ident$, override:Int = False )
  649. If Not override And _env<>Self Return GetDecl( ident )
  650. Local tscope:TScopeDecl=Self
  651. While tscope
  652. Local decl:Object=tscope.GetDecl( ident )
  653. If decl Return decl
  654. tscope=tscope.scope
  655. Wend
  656. End Method
  657. Method GetDeclList:Object( ident$, declList:TFuncDeclList = Null, maxSearchDepth:Int )
  658. If Not declList Then
  659. declList = New TFuncDeclList
  660. End If
  661. Local decl:Object=Object(declsMap.ValueForKey( ident ))
  662. If Not decl Return Null
  663. If TFuncDeclList(decl) Then
  664. For Local fdecl:TFuncDecl = EachIn TFuncDeclList(decl)
  665. If Not fdecl.IsSemanted() Then
  666. fdecl.Semant
  667. End If
  668. Local found:Int
  669. For Local func:TFuncDecl = EachIn declList
  670. If func.equalsFunc(fdecl) Then
  671. found = True
  672. Exit
  673. 'Else
  674. 'Print func.ToString() + " didn't match " + fdecl.ToString()
  675. End If
  676. Next
  677. If Not found Then
  678. declList.AddLast(fdecl)
  679. End If
  680. Next
  681. Return declList
  682. End If
  683. Return decl
  684. End Method
  685. ' returns a list of all matching named decls in scope
  686. Method FindDeclList:Object(ident:String, override:Int = False, declList:TFuncDeclList = Null, maxSearchDepth:Int = SCOPE_ALL )
  687. If Not declList Then
  688. declList = New TFuncDeclList
  689. End If
  690. If Not override And _env<>Self Return GetDeclList( ident, declList, maxSearchDepth )
  691. Local tscope:TScopeDecl=Self
  692. While tscope
  693. Local decl:Object=tscope.GetDeclList( ident, declList, maxSearchDepth )
  694. 'If decl And (Not TFuncDeclList(decl) And declList.IsEmpty()) Return decl
  695. If decl Then
  696. If TFuncDeclList(decl) Then
  697. If TFuncDeclList(decl) <> declList Then
  698. For Local d:TDecl = EachIn TFuncDeclList(decl)
  699. declList.AddLast(d)
  700. Next
  701. End If
  702. Else
  703. declList.AddLast(decl)
  704. End If
  705. End If
  706. ' if scope is an interface, also check implemented/extended interfaces?
  707. If TClassDecl(tscope) And TClassDecl(tscope).IsInterface() Then
  708. If TClassDecl(tscope).implments Then
  709. For Local idecl:TScopeDecl = EachIn TClassDecl(tscope).implments
  710. Local decl:Object=idecl.GetDeclList( ident, declList, maxSearchDepth )
  711. If decl Then
  712. If TFuncDeclList(decl) Then
  713. If TFuncDeclList(decl) <> declList Then
  714. For Local d:TDecl = EachIn TFuncDeclList(decl)
  715. declList.AddLast(d)
  716. Next
  717. End If
  718. Else
  719. declList.AddLast(decl)
  720. End If
  721. End If
  722. Next
  723. End If
  724. End If
  725. tscope=tscope.scope
  726. If TClassDecl(tscope) And maxSearchDepth < SCOPE_CLASS_HEIRARCHY Then
  727. Exit
  728. Else If TModuleDecl(tscope) And maxSearchDepth < SCOPE_ALL Then
  729. Exit
  730. End If
  731. Wend
  732. Return declList
  733. End Method
  734. ' Method FindDecl:Object( ident$, static:Int = False )
  735. ' Local decl:Object=GetDecl( ident )
  736. '
  737. ' If Not static Or Not decl Then
  738. ' If decl Return decl
  739. ' Else
  740. ' If Not TFieldDecl(decl) And Not (TFuncDecl(decl) And TFuncDecl(decl).IsMethod()) Then
  741. ' Return decl
  742. ' End If
  743. ' End If
  744. ' If scope Return scope.FindDecl( ident, static )
  745. ' End Method
  746. Method FindValDecl:TValDecl( ident$, static:Int = False )
  747. Local decl:TValDecl=TValDecl( FindDecl( ident ) )
  748. ' we found a field but we don't have access to it?
  749. If TFieldDecl(decl) And static Then
  750. ' see if there's another decl with the same name elsewhere that we may...
  751. ' field's scope.scope will be a module.
  752. If decl.scope And decl.scope.scope Then
  753. Local vDecl:TValDecl = TValDecl( decl.scope.scope.FindDecl( ident, True ) )
  754. If vDecl Then
  755. decl = vDecl
  756. End If
  757. End If
  758. End If
  759. If Not decl Then
  760. ' try scope search
  761. decl = TValDecl( FindDecl( ident, True ) )
  762. If Not decl Then
  763. ' didn't find it? Maybe it is in module local scope?
  764. ' issue arises when a global initialises with a local variable in the module scope.
  765. Local fdecl:Object = FindDecl("__localmain", True)
  766. If fdecl Then
  767. If TFuncDecl(fdecl) Then
  768. decl = TValDecl( TFuncDecl(fdecl).FindDecl( ident ) )
  769. Else If TFuncDeclList(fdecl) Then
  770. For Local func:TFuncDecl = EachIn TFuncDeclList(fdecl)
  771. func.Semant()
  772. decl = TValDecl( func.FindDecl( ident ) )
  773. If decl Then
  774. Exit
  775. End If
  776. Next
  777. End If
  778. ' a local variable from module local scope can't be seen outside of module local scope...
  779. If TLocalDecl(decl) And static Then
  780. decl = Null
  781. End If
  782. End If
  783. End If
  784. End If
  785. If Not decl Return Null
  786. decl.AssertAccess
  787. decl.Semant
  788. Return decl
  789. End Method
  790. Method FindType:TType( ident$,args:TType[] )
  791. 'DebugLog Self.ident + "::FindType::" + ident
  792. Local decl:Object=(GetDecl( ident ))
  793. If decl Then
  794. If TModuleDecl(decl) Then
  795. decl = TModuleDecl(decl).GetDecl(ident)
  796. End If
  797. Local ty:TType=TType(decl)
  798. If ty
  799. If args.Length Err "Wrong number of type arguments"
  800. Return ty
  801. EndIf
  802. Local cdecl:TClassDecl=TClassDecl( decl )
  803. If cdecl
  804. cdecl.AssertAccess
  805. cdecl=cdecl.GenClassInstance( args )
  806. cdecl.Semant
  807. Return cdecl.objectType
  808. EndIf
  809. EndIf
  810. If scope Return scope.FindType( ident,args )
  811. End Method
  812. Method FindScopeDecl:TScopeDecl( ident$ )
  813. Local decl:TScopeDecl=TScopeDecl( FindDecl( ident ) )
  814. If Not decl Return Null
  815. decl.AssertAccess
  816. decl.Semant
  817. Return decl
  818. End Method
  819. Rem
  820. Method FindClassDecl:TClassDecl( ident$,args:TClassDecl[] = Null )
  821. Local decl:TClassDecl=TClassDecl( GetDecl( ident ) )
  822. If Not args Then
  823. args = New TClassDecl[0]
  824. End If
  825. If Not decl
  826. If scope Return scope.FindClassDecl( ident,args )
  827. Return Null
  828. EndIf
  829. decl.AssertAccess
  830. decl.Semant
  831. Return decl.GenClassInstance( args )
  832. End Method
  833. End Rem
  834. Method FindModuleDecl:TModuleDecl( ident$ )
  835. 'DebugStop
  836. Local decl:TModuleDecl=TModuleDecl( GetDecl( ident ) )
  837. If Not decl
  838. If scope Return scope.FindModuleDecl( ident )
  839. Return Null
  840. EndIf
  841. decl.AssertAccess
  842. ' only semant on "real" module
  843. If Not decl.declImported Then
  844. decl.Semant
  845. End If
  846. Return decl
  847. End Method
  848. Method FindBestMatchForArgs:TFuncDecl(argExprs:TExpr[], matches:TList)
  849. Local bestMatch:TFuncDecl = Null
  850. Local totals:Int[] = New Int[matches.count()]
  851. Local index:Int
  852. For Local func:TFuncDecl = EachIn matches
  853. Local argDecls:TArgDecl[]=func.argDecls
  854. For Local i:Int=0 Until argDecls.Length
  855. If i<argExprs.Length And argExprs[i]
  856. Local declTy:TType=argDecls[i].ty
  857. Local exprTy:TType=argExprs[i].exprType
  858. If TFunctionPtrType(declTy) And TInvokeExpr(argExprs[i]) Then
  859. If TFunctionPtrType(declTy).equalsDecl(TInvokeExpr(argExprs[i]).decl) Then
  860. Continue
  861. End If
  862. End If
  863. ' not ideal - since the arg is configured as a Byte Ptr, we can't check that the function is of the correct type.
  864. If IsPointerType(declTy, TType.T_BYTE) And TInvokeExpr(argExprs[i]) And TInvokeExpr(argExprs[i]).invokedWithBraces = 0 Then
  865. Continue
  866. End If
  867. If TFunctionPtrType(declTy) And IsPointerType(exprTy, TType.T_BYTE) Then
  868. Continue
  869. End If
  870. If exprTy.EqualsType( declTy ) Continue
  871. ' not an exact match. increase distance...
  872. totals[index] :+ exprTy.DistanceToType(declTy)
  873. End If
  874. Next
  875. index :+ 1
  876. Next
  877. Local tot:Int = -1
  878. index = 0
  879. Local i:Int
  880. For Local func:TFuncDecl = EachIn matches
  881. If tot = -1 Or totals[i] < tot Then
  882. tot = totals[i]
  883. bestMatch = func
  884. Else If tot = totals[i] Then
  885. If bestMatch.IsMethod() And Not func.IsMethod() Then
  886. '
  887. Else If Not bestMatch.IsMethod() And func.IsMethod() Then
  888. bestMatch = func
  889. Else If (bestMatch.scope <> func.scope) And (TClassDecl(bestMatch.scope).ExtendsClass(TClassDecl(func.scope))) Then
  890. ' match is in different level of class hierarchy
  891. Exit
  892. Else
  893. ' a tie?
  894. Err "Unable to determine overload to use: "+ bestMatch.ToString()+" or "+func.ToString()+"."
  895. End If
  896. End If
  897. i :+ 1
  898. Next
  899. Return bestMatch
  900. End Method
  901. Method FindFuncDecl:TFuncDecl( ident$,argExprs:TExpr[] = Null,explicit:Int=False, isArg:Int = False, isIdentExpr:Int = False, throwOnNotMatched:Int = False, maxSearchDepth:Int )
  902. 'DebugLog "FindFuncDecl : " + ident
  903. 'If ident = "new" Then DebugStop
  904. Local foundIdentMatch:Int
  905. Local funcs:TFuncDeclList
  906. ' does ident exist?
  907. Local f:Object = FindDeclList(ident, True,,maxSearchDepth)
  908. If Not f Then Return Null
  909. funcs = TFuncDeclList( f )
  910. Local fp:TFuncDecl
  911. ' not a function list, test for a function ptr var
  912. If Not funcs Or funcs.IsEmpty() Then
  913. ' we found a funcdecl
  914. If TFuncDecl(f) Then
  915. funcs = New TFuncDeclList
  916. funcs.AddLast(f)
  917. End If
  918. If TVarDecl(f) Then
  919. If Not TVarDecl(f).IsSemanted() Then
  920. TVarDecl(f).Semant()
  921. End If
  922. If TFunctionPtrType(TVarDecl(f).ty) Then
  923. funcs = New TFuncDeclList
  924. fp = TFunctionPtrType(TVarDecl(f).ty).func
  925. If Not fp.scope Then
  926. fp.scope = TVarDecl(f).scope
  927. End If
  928. If Not fp.ident Then
  929. fp.ident = TVarDecl(f).ident
  930. End If
  931. funcs.AddLast fp
  932. End If
  933. End If
  934. End If
  935. ' was neither... lets bug out
  936. If Not funcs Return Null
  937. ' If Not funcs Then Return Null
  938. For Local func:TDecl = EachIn funcs
  939. func.Semant()
  940. Next
  941. 'Local f:TDecl = TDecl(findDecl(ident))
  942. 'If Not f Then Return Null
  943. 'Local func:TFuncDecl = TFuncDecl(f)
  944. ' If Not func Then
  945. ' If TVarDecl(f) Then
  946. ' If Not f.IsSemanted() Then
  947. ' f.Semant()
  948. ' End If
  949. ' If TFunctionPtrType(TVarDecl(f).ty) Then
  950. ' func = TFunctionPtrType(TVarDecl(f).ty).func
  951. ' If Not func.scope Then
  952. ' func.scope = f.scope
  953. ' End If
  954. ' If Not func.ident Then
  955. ' func.ident = f.ident
  956. ' End If
  957. ' End If
  958. ' End If
  959. ' End If
  960. ' If Not func Return Null
  961. If Not argExprs
  962. argExprs = New TExpr[0]
  963. End If
  964. 'func.Semant()
  965. Local match:TFuncDecl,isexact:Int
  966. Local _err$
  967. Local errorDetails:String
  968. Local matches:TList = New TList
  969. Local noExtendString:Int = True
  970. Local generateWarnings:Int = False
  971. ' double test for matches.
  972. ' * first time through we don't allow up-casting args to String
  973. ' if we get a match on the first pass, we'll take it.
  974. ' * second iteration we allow up-casting numerics to string
  975. ' * third iteration is valid if opt_warnover is enabled
  976. ' this will allow down-casting of numerics (eg. double->float)
  977. ' warnings will be generated if this produces valid results.
  978. ' if after all that, there's no match, then we can fail it.
  979. For Local n:Int = 0 Until 3
  980. If n > 1 Then
  981. If Not opt_warnover Then
  982. Continue
  983. Else
  984. generateWarnings = True
  985. End If
  986. End If
  987. errorDetails = ""
  988. If n Then
  989. noExtendString = False
  990. End If
  991. For Local iDecl:TDecl = EachIn funcs
  992. Local func:TFuncDecl = TFuncDecl(iDecl)
  993. If Not func Then
  994. If TVarDecl(iDecl) Then
  995. ' If Not TVarDecl(iDecl).IsSemanted() Then
  996. ' TVarDecl(f).Semant()
  997. ' End If
  998. If TFunctionPtrType(TVarDecl(iDecl).ty) Then
  999. 'funcs = New TFuncDeclList
  1000. fp = TFunctionPtrType(TVarDecl(iDecl).ty).func
  1001. If Not fp.scope Then
  1002. fp.scope = TVarDecl(iDecl).scope
  1003. End If
  1004. If Not fp.ident Then
  1005. fp.ident = TVarDecl(iDecl).ident
  1006. End If
  1007. 'funcs.AddLast fp
  1008. func = fp
  1009. End If
  1010. End If
  1011. If Not func Then
  1012. Continue
  1013. End If
  1014. End If
  1015. 'While True
  1016. If Not func.CheckAccess() Continue
  1017. Local argDecls:TArgDecl[]=func.argDecls
  1018. Local exact:Int=True
  1019. Local possible:Int=True
  1020. foundIdentMatch = True
  1021. ' we found a matching name - this is probably the one we mean...
  1022. If isArg Then
  1023. 'match=func
  1024. matches.AddLast(func)
  1025. Exit
  1026. End If
  1027. If argExprs.Length>argDecls.Length
  1028. exact = False
  1029. Continue
  1030. End If
  1031. For Local i:Int=0 Until argDecls.Length
  1032. If i<argExprs.Length And argExprs[i]
  1033. Local arg:TExpr = argExprs[i]
  1034. Local declTy:TType=argDecls[i].ty
  1035. Local exprTy:TType=arg.exprType
  1036. Local widensTest:Int = True
  1037. ' for numeric constants, allow them to be auto-cast unless
  1038. If TConstExpr(arg) And IsNumericType(exprTy) And Not TConstExpr(arg).typeSpecific And TConstExpr(arg).CompatibleWithType(declTy) Then
  1039. widensTest = False
  1040. End If
  1041. If TFunctionPtrType(declTy) And TInvokeExpr(arg) Then
  1042. If TFunctionPtrType(declTy).equalsDecl(TInvokeExpr(arg).decl) Continue
  1043. End If
  1044. ' not ideal - since the arg is configured as a Byte Ptr, we can't check that the function is of the correct type.
  1045. If IsPointerType(declTy, TType.T_BYTE) And TInvokeExpr(arg) And TInvokeExpr(arg).invokedWithBraces = 0 Then
  1046. Continue
  1047. End If
  1048. If TFunctionPtrType(declTy) And IsPointerType(exprTy, TType.T_BYTE) Then
  1049. Continue
  1050. End If
  1051. If exprTy.EqualsType( declTy ) Continue
  1052. exact=False
  1053. If Not generateWarnings Then
  1054. If Not explicit And exprTy.ExtendsType( declTy, noExtendString, widensTest ) Continue
  1055. Else
  1056. If Not explicit Then
  1057. ' fails widen test
  1058. If Not exprTy.ExtendsType( declTy, noExtendString, True ) Then
  1059. ' but passes non-widen test
  1060. If exprTy.ExtendsType( declTy, noExtendString, False ) Then
  1061. ' generate a warning, and accept it
  1062. Warn "In call to " + func.ToString()+ ". Argument #"+(i+1)+" is ~q" + exprTy.ToString()+"~q but declaration is ~q"+declTy.ToString()+"~q. "
  1063. Continue
  1064. End If
  1065. Else
  1066. Continue
  1067. End If
  1068. End If
  1069. End If
  1070. ' make a more helpful error message
  1071. errorDetails :+ "Argument #"+(i+1)+" is ~q" + exprTy.ToString()+"~q but declaration is ~q"+declTy.ToString()+"~q. "
  1072. Else If Not argDecls[i].init
  1073. If (func.attrs & FUNC_PTR) Or isIdentExpr Then
  1074. exact=False
  1075. Exit
  1076. End If
  1077. ' if this argument is missing and there isn't a default...
  1078. errorDetails :+ "Missing function parameter '" + argDecls[i].ident + "'"
  1079. Else ' for case of argdecls having default args
  1080. exact=False
  1081. If Not explicit Exit
  1082. EndIf
  1083. possible=False
  1084. Exit
  1085. Next
  1086. If Not possible Continue
  1087. If exact
  1088. If isexact
  1089. Err "Unable to determine overload to use: "+match.ToString()+" or "+func.ToString()+"."
  1090. Else
  1091. _err=""
  1092. 'match=func
  1093. matches.AddLast(func)
  1094. isexact=True
  1095. Exit
  1096. EndIf
  1097. Else
  1098. If Not isexact
  1099. 'If match
  1100. ' _err="Unable to determine overload to use: "+match.ToString()+" or "+func.ToString()+"."
  1101. 'Else
  1102. 'match=func
  1103. matches.AddLast(func)
  1104. 'EndIf
  1105. EndIf
  1106. EndIf
  1107. 'Exit
  1108. Next
  1109. If Not matches.IsEmpty() Then
  1110. Exit
  1111. End If
  1112. Next
  1113. If matches.Count() = 1 Then
  1114. match = TFuncDecl(matches.First())
  1115. Else
  1116. ' find best match
  1117. match = FindBestMatchForArgs(argExprs, matches)
  1118. End If
  1119. If Not isexact
  1120. If _err Err _err
  1121. If explicit Return Null
  1122. EndIf
  1123. ' last try... maybe we are trying to use it as a function pointer? (no args)
  1124. If Not match Then
  1125. If argExprs Then
  1126. 'match = func
  1127. ' match.maybeFunctionPtr = True
  1128. End If
  1129. Else If Not argExprs Then
  1130. ' if there are no args, the actual function may have none either... so we may still be trying to use it as a function pointer
  1131. match.maybeFunctionPtr = True
  1132. End If
  1133. If Not match
  1134. Local t$
  1135. For Local i:Int=0 Until argExprs.Length
  1136. If t t:+","
  1137. If argExprs[i] t:+argExprs[i].exprType.ToString()
  1138. Next
  1139. If foundIdentMatch Then
  1140. If throwOnNotMatched Then
  1141. Throw "Unable to find overload for "+ident+"("+t+"). " + errorDetails
  1142. Else
  1143. Err "Unable to find overload for "+ident+"("+t+"). " + errorDetails
  1144. End If
  1145. Else
  1146. If throwOnNotMatched Then
  1147. Throw "Identifier '" + ident + "' not found."
  1148. Else
  1149. Err "Identifier '" + ident + "' not found."
  1150. End If
  1151. End If
  1152. EndIf
  1153. match.AssertAccess
  1154. Return match
  1155. End Method
  1156. Method FindLoop:TStmt(ident:String = Null)
  1157. If TBlockDecl(Self) And TBlockDecl(Self).extra Then
  1158. Local loop:TLoopStmt = TLoopStmt(TBlockDecl(Self).extra)
  1159. If ident Then
  1160. If loop.loopLabel And loop.loopLabel.IdentLower() = ident Then
  1161. Return loop
  1162. End If
  1163. Else
  1164. Return loop
  1165. End If
  1166. End If
  1167. If TFuncDecl(scope) Or TModuleDecl(scope)
  1168. Return Null
  1169. End If
  1170. If scope Return scope.FindLoop( ident )
  1171. End Method
  1172. Method OnSemant()
  1173. End Method
  1174. End Type
  1175. Type TBlockDecl Extends TScopeDecl
  1176. Field stmts:TList=New TList
  1177. Field extra:Object
  1178. Method Create:TBlockDecl( scope:TScopeDecl, generated:Int = False )
  1179. Self.scope=scope
  1180. Self.generated = generated
  1181. attrs :| (scope.attrs & DECL_NODEBUG)
  1182. Return Self
  1183. End Method
  1184. Method AddStmt( stmt:TStmt )
  1185. stmts.AddLast stmt
  1186. End Method
  1187. Method OnCopy:TDecl(deep:Int = True)
  1188. Local t:TBlockDecl=New TBlockDecl
  1189. If deep Then
  1190. For Local stmt:TStmt=EachIn stmts
  1191. t.AddStmt stmt.Copy( t )
  1192. Next
  1193. End If
  1194. t.extra = extra
  1195. t.generated = generated
  1196. Return t
  1197. End Method
  1198. Method OnSemant()
  1199. PushEnv Self
  1200. For Local stmt:TStmt=EachIn stmts
  1201. stmt.Semant
  1202. Next
  1203. PopEnv
  1204. End Method
  1205. Method CopyBlock:TBlockDecl( scope:TScopeDecl )
  1206. Local t:TBlockDecl=TBlockDecl( Copy() )
  1207. t.scope=scope
  1208. Return t
  1209. End Method
  1210. End Type
  1211. Const FUNC_METHOD:Int= $0001 'mutually exclusive with ctor
  1212. Const FUNC_CTOR:Int= $0002
  1213. Const FUNC_PROPERTY:Int= $0004
  1214. Const FUNC_DTOR:Int= $0008
  1215. Const FUNC_PTR:Int= $0100
  1216. Const FUNC_BUILTIN:Int = $0080
  1217. Const FUNC_INIT:Int = $0200
  1218. Const FUNC_NESTED:Int = $0400
  1219. Const FUNC_OPERATOR:Int= $0800
  1220. 'Fix! A func is NOT a block/scope!
  1221. '
  1222. Type TFuncDecl Extends TBlockDecl
  1223. Field retType:TType
  1224. Field retTypeExpr:TType
  1225. Field argDecls:TArgDecl[]
  1226. Field overrides:TFuncDecl
  1227. Field superCtor:TInvokeSuperExpr
  1228. Field castTo:String
  1229. Field noCastGen:Int
  1230. Field maybeFunctionPtr:Int
  1231. Field returnTypeSubclassed:Int
  1232. Field mangled:String
  1233. Field noMangle:Int
  1234. Field equalsBuiltIn:Int = -1
  1235. Method CreateF:TFuncDecl( ident$,ty:TType,argDecls:TArgDecl[],attrs:Int )
  1236. Self.ident=ident
  1237. Self.retTypeExpr=ty
  1238. If argDecls
  1239. Self.argDecls=argDecls
  1240. Else
  1241. Self.argDecls = New TArgDecl[0]
  1242. End If
  1243. Self.attrs=attrs
  1244. Return Self
  1245. End Method
  1246. Method OnCopy:TDecl(deep:Int = True)
  1247. Local args:TArgDecl[]=argDecls[..]
  1248. For Local i:Int=0 Until args.Length
  1249. args[i]=TArgDecl( args[i].Copy() )
  1250. Next
  1251. Local t:TFuncDecl=New TFuncDecl.CreateF( ident,retType,args,attrs )
  1252. If deep Then
  1253. For Local stmt:TStmt=EachIn stmts
  1254. t.AddStmt stmt.Copy( t )
  1255. Next
  1256. End If
  1257. t.retType = retType
  1258. t.scope = scope
  1259. t.overrides = overrides
  1260. t.superCtor = superCtor
  1261. t.castTo = castTo
  1262. t.noCastGen = noCastGen
  1263. t.munged = munged
  1264. t.metadata = metadata
  1265. t.mangled = mangled
  1266. t.noMangle = noMangle
  1267. Return t
  1268. End Method
  1269. Method GenInstance:TDecl()
  1270. Local inst:TFuncDecl=New TFuncDecl
  1271. InitInstance inst
  1272. inst.retTypeExpr=retTypeExpr
  1273. inst.argDecls=argDecls[..]
  1274. For Local i:Int=0 Until argDecls.Length
  1275. inst.argDecls[i]=TArgDecl( argDecls[i].GenInstance() )
  1276. Next
  1277. Return inst
  1278. End Method
  1279. Method ToString$()
  1280. Local t$
  1281. For Local decl:TArgDecl=EachIn argDecls
  1282. If t t:+","
  1283. t:+decl.ToString()
  1284. Next
  1285. Local q$
  1286. If IsCtor()
  1287. q="Method "+Super.ToString()
  1288. Else
  1289. If IsMethod() q="Method " Else q="Function "
  1290. q:+Super.ToString()
  1291. If retType
  1292. If Not TVoidType(retType) Then
  1293. q:+":"+retType.ToString()
  1294. End If
  1295. Else If retTypeExpr
  1296. q:+":"+retTypeExpr.ToString()
  1297. 'Else
  1298. ' q:+":"+"?"
  1299. EndIf
  1300. EndIf
  1301. Return q+"("+t+")"
  1302. End Method
  1303. Method ToTypeString:String()
  1304. Local t$
  1305. For Local decl:TArgDecl=EachIn argDecls
  1306. If t t:+","
  1307. t:+decl.ToTypeString()
  1308. Next
  1309. Local q$
  1310. If Not IsCtor() Then
  1311. If retType
  1312. If Not TVoidType(retType) Then
  1313. q:+retType.ToString()
  1314. End If
  1315. Else If retTypeExpr
  1316. q:+retTypeExpr.ToString()
  1317. EndIf
  1318. End If
  1319. Return q+"("+t+")"
  1320. End Method
  1321. Method IsBuiltIn:Int()
  1322. Return (attrs & FUNC_BUILTIN)<>0
  1323. End Method
  1324. Method IsCtor:Int()
  1325. Return (attrs & FUNC_CTOR)<>0
  1326. End Method
  1327. Method IsDtor:Int()
  1328. Return (attrs & FUNC_DTOR)<>0
  1329. End Method
  1330. Method IsMethod:Int()
  1331. Return (attrs & FUNC_METHOD)<>0
  1332. End Method
  1333. Method IsAnyMethod:Int()
  1334. Return IsMethod() Or IsCtor() Or IsDtor()
  1335. End Method
  1336. Method IsStatic:Int()
  1337. Return (attrs & (FUNC_METHOD|FUNC_CTOR))=0
  1338. End Method
  1339. Method IsProperty:Int()
  1340. Return (attrs & FUNC_PROPERTY)<>0
  1341. End Method
  1342. Method EqualsArgs:Int( decl:TFuncDecl )
  1343. If argDecls.Length<>decl.argDecls.Length Return False
  1344. For Local i:Int=0 Until argDecls.Length
  1345. If Not argDecls[i].ty.EqualsType( decl.argDecls[i].ty ) Return False
  1346. Next
  1347. Return True
  1348. End Method
  1349. Method EqualsFunc:Int( decl:TFuncDecl )
  1350. If IsCtor() Then
  1351. Return EqualsArgs( decl )
  1352. Else
  1353. Return (retType.EqualsType( decl.retType ) Or retType.ExtendsType( decl.retType ) Or decl.retType.EqualsType( retType )) And EqualsArgs( decl )
  1354. End If
  1355. End Method
  1356. Method OnSemant()
  1357. Local strictVoidToInt:Int = False
  1358. 'semant ret type
  1359. If Not retTypeExpr Then
  1360. If Not retType Then ' may have previously been set (if this is a function pointer)
  1361. retType = TType.voidType
  1362. Else If TIdentType(retType)
  1363. retType = retType.Semant()
  1364. Else
  1365. ' for Strict code, a void return type becomes Int
  1366. If TVoidType(retType) And Not ModuleScope().IsSuperStrict() Then
  1367. strictVoidToInt = True
  1368. retType = New TIntType
  1369. End If
  1370. End If
  1371. Else
  1372. ' pass the scope into the function ptr
  1373. Local retTypeExpr_:TType = retTypeExpr
  1374. While TArrayType(retTypeExpr_) ' look into array types, since the element type might be function ptr
  1375. retTypeExpr_ = TArrayType(retTypeExpr_).elemType
  1376. Wend
  1377. If TFunctionPtrType(retTypeExpr_) Then
  1378. If Not TFunctionPtrType(retTypeExpr_).func.scope Then
  1379. If scope Then
  1380. TFunctionPtrType(retTypeExpr_).func.scope = scope
  1381. Else
  1382. TFunctionPtrType(retTypeExpr_).func.scope = _env
  1383. End If
  1384. End If
  1385. End If
  1386. retType=retTypeExpr.Semant()
  1387. ' for Strict code, a void return type becomes Int
  1388. If TVoidType(retType) And Not ModuleScope().IsSuperStrict() And Not IsDTor() Then
  1389. strictVoidToInt = True
  1390. retType = New TIntType
  1391. End If
  1392. End If
  1393. If TArrayType( retType ) And Not retType.EqualsType( retType.ActualType() )
  1394. ' Err "Return type cannot be an array of generic objects."
  1395. EndIf
  1396. 'semant args
  1397. For Local arg:TArgDecl=EachIn argDecls
  1398. InsertDecl arg
  1399. arg.Semant
  1400. Next
  1401. ' if we are a function pointer declaration, we just want to semant the args here.
  1402. If attrs & FUNC_PTR Return
  1403. If actual<>Self Return
  1404. 'check for duplicate decl
  1405. If ident Then
  1406. For Local decl:TFuncDecl=EachIn scope.SemantedFuncs( ident )
  1407. If decl<>Self And EqualsArgs( decl )
  1408. Err "Duplicate declaration "+ToString()
  1409. EndIf
  1410. If noMangle Then
  1411. If decl<>Self Then
  1412. If decl.argDecls.Length = 0 Then
  1413. Err "You cannot apply NoMangle to the function, as another function with no arguments exists."
  1414. Else If decl.NoMangle Then
  1415. Err "Another function is already declared with NoMangle."
  1416. End If
  1417. End If
  1418. End If
  1419. Next
  1420. End If
  1421. ' any nested functions?
  1422. For Local fdecl:TFuncDecl = EachIn _decls
  1423. fdecl.Semant
  1424. Next
  1425. 'get cdecl, sclasss
  1426. Local cdecl:TClassDecl=ClassScope(),sclass:TClassDecl
  1427. If cdecl sclass=TClassDecl( cdecl.superClass )
  1428. 'prefix call to super ctor if necessary
  1429. ' If IsCtor() And superCtor=Null And sclass
  1430. ' If sclass.FindFuncDecl( "new", Null )
  1431. ' superCtor=New TInvokeSuperExpr.Create( "new" )
  1432. ' stmts.AddFirst New TExprStmt.Create( superCtor )
  1433. ' EndIf
  1434. ' EndIf
  1435. 'check we exactly match an override
  1436. If sclass 'And IsMethod()
  1437. While sclass
  1438. Local errorDetails:String = ""
  1439. Local found:Int
  1440. For Local decl:TFuncDecl=EachIn sclass.FuncDecls( )
  1441. If decl.IdentLower() = IdentLower() Then
  1442. If IdentLower() = "new" Continue
  1443. If IdentLower() = "delete" Continue
  1444. found=True
  1445. If Not decl.IsSemanted() Then
  1446. decl.Semant
  1447. End If
  1448. ' check void return type strictness, and fail if appropriate.
  1449. Local voidReturnTypeFail:Int = False
  1450. ' super has void return type... so it is superstrict (or inherited from)
  1451. If TVoidType(decl.retType) And TIntType(retType) Then
  1452. ' if we are only strict, we may fail on type mismatch
  1453. If Not ModuleScope().IsSuperStrict() Then
  1454. ' we have the option of upgrading our return type to match superstrict parent
  1455. If opt_strictupgrade And strictVoidToInt Then
  1456. retType = TType.voidType
  1457. Else
  1458. ' otherwise...
  1459. voidReturnTypeFail = True
  1460. End If
  1461. End If
  1462. End If
  1463. If EqualsFunc( decl ) And Not voidReturnTypeFail
  1464. ' check we aren't attempting to assign weaker access modifiers
  1465. If (IsProtected() And decl.IsPublic()) Or (IsPrivate() And (decl.IsProtected() Or decl.IsPublic())) Then
  1466. Local p:String
  1467. If IsProtected() Then
  1468. p = "Protected"
  1469. Else
  1470. p = "Private"
  1471. End If
  1472. Local dp:String
  1473. If decl.IsPublic() Then
  1474. dp = "Public"
  1475. Else
  1476. dp = "Protected"
  1477. End If
  1478. Err ToString() + " clashes with " + decl.ToString() + ". Attempt to assign weaker access privileges ('" + p + "'), was '" + dp + "'."
  1479. End If
  1480. If Not retType.EqualsType( decl.retType ) And retType.ExtendsType( decl.retType ) Then
  1481. returnTypeSubclassed = True
  1482. End If
  1483. overrides=TFuncDecl( decl.actual )
  1484. Else
  1485. 'prepare a more detailed error message
  1486. If (Not retType.EqualsType( decl.retType ) Or Not retType.ExtendsType( decl.retType )) Or (decl.retType And Not decl.retType.EqualsType( retType )) Or voidReturnTypeFail
  1487. errorDetails :+ "Return type is ~q"+retType.ToString()+"~q, expected ~q"+decl.retType.ToString()+"~q. "
  1488. If voidReturnTypeFail Then
  1489. errorDetails :+ "You may have Strict type overriding SuperStrict type. "
  1490. End If
  1491. Else
  1492. found = False
  1493. Continue
  1494. End If
  1495. ' TODO REMOVE
  1496. ' the following doesn't apply when supporting overloading, as we can have methods of the same name with different args length/types
  1497. If argDecls.Length <> decl.argDecls.Length
  1498. errorDetails :+ "Argument count differs. Got " + argDecls.Length +", expected " + decl.argDecls.Length + " arguments."
  1499. End If
  1500. Local argCount:Int = Min(argDecls.Length, decl.argDecls.Length)
  1501. If argCount > 0
  1502. For Local i:Int=0 Until argCount
  1503. If Not argDecls[i].ty.EqualsType( decl.argDecls[i].ty )
  1504. errorDetails :+ "Argument #"+(i+1)+" is ~q" + argDecls[i].ty.ToString()+"~q, expected ~q"+decl.argDecls[i].ty.ToString()+"~q. "
  1505. End If
  1506. Next
  1507. EndIf
  1508. 'remove last space
  1509. errorDetails = errorDetails.Trim()
  1510. EndIf
  1511. End If
  1512. Next
  1513. If found
  1514. If Not overrides Err "Overriding method does not match any overridden method. (Detail: " + errorDetails+")"
  1515. ' for overrides, make the ident match that of the superclass
  1516. ident = overrides.ident
  1517. Exit
  1518. EndIf
  1519. sclass=sclass.superClass
  1520. Wend
  1521. EndIf
  1522. 'append a return statement if necessary
  1523. If Not IsExtern() And Not TVoidType( retType ) And Not TReturnStmt( stmts.Last() )
  1524. If Not isCtor() And Not isDtor()
  1525. Local stmt:TReturnStmt
  1526. stmt=New TReturnStmt.Create( New TConstExpr.Create( retType,"" ) )
  1527. stmt.generated = True
  1528. stmt.errInfo=errInfo
  1529. stmts.AddLast stmt
  1530. End If
  1531. EndIf
  1532. attrs:|DECL_SEMANTED
  1533. Super.OnSemant()
  1534. End Method
  1535. Method CheckAccess:Int()
  1536. Local cd:TClassDecl = ClassScope()
  1537. If cd Then
  1538. If IsPrivate() And cd<>_env.ClassScope() Return False
  1539. If IsProtected() Then
  1540. Local ec:TClassDecl = _env.ClassScope()
  1541. If Not ec Return False
  1542. If Not ec.ExtendsClass(cd) Return False
  1543. End If
  1544. Return True
  1545. End If
  1546. Return Super.CheckAccess()
  1547. End Method
  1548. End Type
  1549. Type TNewDecl Extends TFuncDecl
  1550. Field chainedCtor:TNewExpr
  1551. End Type
  1552. 'Const CLASS_INTERFACE:Int=1
  1553. 'Const CLASS_TEMPLATEARG:Int=2
  1554. 'Const CLASS_TEMPLATEINST:Int=4
  1555. 'Const CLASS_INSTANCED:Int=8 'class used in New?
  1556. Const CLASS_INSTANCED:Int=1
  1557. Const CLASS_EXTENDSOBJECT:Int=2
  1558. Const CLASS_FINALIZED:Int=4
  1559. Type TNullDecl Extends TClassDecl
  1560. End Type
  1561. Type TClassDecl Extends TScopeDecl
  1562. Field lastOffset:Int
  1563. Field args:String[]
  1564. Field superTy:TIdentType
  1565. Field impltys:TIdentType[]
  1566. Field superClass:TClassDecl
  1567. Field implments:TClassDecl[] 'interfaces immediately implemented
  1568. Field implmentsAll:TClassDecl[] 'all interfaces implemented
  1569. Field instanceof:TClassDecl 'for instances
  1570. Field instances:TList 'for actual (non-arg, non-instance)
  1571. Field instArgs:TType[]
  1572. Field objectType:TObjectType '"canned" objectType
  1573. Field globInit:Int
  1574. 'Global nullObjectClass:TClassDecl=New TNullDecl.Create( "{NULL}",Null,Null,Null,DECL_ABSTRACT|DECL_EXTERN )
  1575. Method Create:TClassDecl( ident$,args:String[],superTy:TIdentType,impls:TIdentType[],attrs:Int )
  1576. Self.ident=ident
  1577. Self.args=args
  1578. Self.superTy=superTy
  1579. Self.impltys=impls
  1580. Self.attrs=attrs
  1581. Self.objectType=New TObjectType.Create( Self )
  1582. If args
  1583. instances=New TList
  1584. instances.AddLast Self
  1585. EndIf
  1586. Return Self
  1587. End Method
  1588. Method OnCopy:TDecl(deep:Int = True)
  1589. InternalErr
  1590. End Method
  1591. Method ToString$()
  1592. Local t$
  1593. If args Then
  1594. For Local i:Int=0 Until args.Length
  1595. If i t:+","
  1596. t:+args[i].ToString()
  1597. Next
  1598. ElseIf instargs
  1599. End If
  1600. If t t="<"+t+">"
  1601. Return ident+t
  1602. End Method
  1603. Method ToTypeString:String()
  1604. Return ident
  1605. End Method
  1606. Rem
  1607. Method GenClassInstance:TClassDecl( instArgs:TClassDecl[] )
  1608. If Not IsSemanted() InternalErr
  1609. 'no args
  1610. If Not instArgs
  1611. If Not args Return Self
  1612. If instanceof Return Self
  1613. For Local inst:TClassDecl=EachIn instances
  1614. If _env.ClassScope()=inst Return inst
  1615. Next
  1616. EndIf
  1617. 'If Not instanceof And Not instArgs Return Self
  1618. 'check number of args
  1619. If instanceof Or args.Length<>instArgs.Length
  1620. Err "Wrong number of class arguments for "+ToString()
  1621. EndIf
  1622. 'look for existing instance
  1623. For Local inst:TClassDecl=EachIn instances
  1624. Local equal:Int=True
  1625. For Local i:Int=0 Until args.Length
  1626. If inst.args[i]=instArgs[i] Continue
  1627. equal=False
  1628. Exit
  1629. Next
  1630. If equal Return inst
  1631. Next
  1632. Local inst:TClassDecl=New TClassDecl
  1633. InitInstance inst
  1634. inst.scope=scope
  1635. inst.attrs:|CLASS_TEMPLATEINST
  1636. inst.args=instArgs
  1637. inst.superTy=superTy
  1638. inst.instanceof=Self
  1639. instances.AddLast inst
  1640. For Local i:Int=0 Until args.Length
  1641. inst.InsertDecl New TAliasDecl.Create( args[i].ident,instArgs[i] )
  1642. Next
  1643. For Local decl:TDecl=EachIn _decls
  1644. If TClassDecl( decl ) Continue
  1645. inst.InsertDecl decl.GenInstance()
  1646. Next
  1647. 'inst.Semant
  1648. 'A bit cheeky...
  1649. inst.OnSemant
  1650. inst.attrs:|DECL_SEMANTED
  1651. Return inst
  1652. End Method
  1653. End Rem
  1654. Method GenClassInstance:TClassDecl( instArgs:TType[] )
  1655. If instanceof InternalErr
  1656. 'no args
  1657. If Not instArgs
  1658. If Not args Return Self
  1659. For Local inst:TClassDecl=EachIn instances
  1660. If _env.ClassScope()=inst Return inst
  1661. Next
  1662. EndIf
  1663. 'check number of args
  1664. If args.Length<>instArgs.Length
  1665. Err "Wrong number of type arguments for class "+ToString()
  1666. EndIf
  1667. 'look for existing instance
  1668. For Local inst:TClassDecl=EachIn instances
  1669. Local equal:Int=True
  1670. For Local i:Int=0 Until args.Length
  1671. If Not inst.instArgs[i].EqualsType( instArgs[i] )
  1672. equal=False
  1673. Exit
  1674. EndIf
  1675. Next
  1676. If equal Return inst
  1677. Next
  1678. Local inst:TClassDecl=New TClassDecl.Create( ident,Null,superTy,impltys, attrs )
  1679. inst.attrs:&~DECL_SEMANTED
  1680. inst.munged=munged
  1681. inst.errInfo=errInfo
  1682. inst.scope=scope
  1683. inst.instanceof=Self
  1684. inst.instArgs=instArgs
  1685. instances.AddLast inst
  1686. For Local i:Int=0 Until args.Length
  1687. inst.InsertDecl New TAliasDecl.Create( args[i].ToString(),instArgs[i],0 )
  1688. Next
  1689. For Local decl:TDecl=EachIn _decls
  1690. inst.InsertDecl decl.Copy()
  1691. Next
  1692. Return inst
  1693. End Method
  1694. Method IsInterface:Int()
  1695. Return (attrs & CLASS_INTERFACE)<>0
  1696. End Method
  1697. Method IsFinal:Int()
  1698. Return (attrs & DECL_FINAL)<>0
  1699. End Method
  1700. Method IsThrowable:Int()
  1701. Return (attrs & CLASS_THROWABLE)<>0
  1702. End Method
  1703. Method IsFinalized:Int()
  1704. Return (attrs & CLASS_FINALIZED)<>0
  1705. End Method
  1706. Method IsStruct:Int()
  1707. Return (attrs & CLASS_STRUCT)<>0
  1708. End Method
  1709. Method ExtendsObject:Int()
  1710. Return (attrs & CLASS_EXTENDSOBJECT)<>0
  1711. End Method
  1712. Method IsInstanced:Int()
  1713. Return (attrs & CLASS_INSTANCED)<>0
  1714. End Method
  1715. Method GetDecl:Object( ident$ )
  1716. Local cdecl:TClassDecl=Self
  1717. While cdecl
  1718. Local decl:Object=cdecl.GetDecl2( ident )
  1719. If decl Return decl
  1720. cdecl=cdecl.superClass
  1721. Wend
  1722. End Method
  1723. 'needs this 'coz you can't go blah.Super.GetDecl()...
  1724. Method GetDecl2:Object( ident$ )
  1725. Return Super.GetDecl( ident )
  1726. End Method
  1727. Method GetDeclList:Object( ident$, declList:TFuncDeclList = Null, maxSearchDepth:Int )
  1728. If Not declList Then
  1729. declList = New TFuncDeclList
  1730. End If
  1731. Local cdecl:TClassDecl=Self
  1732. While cdecl
  1733. Local decl:Object=cdecl.GetDeclList2( ident, declList, maxSearchDepth )
  1734. 'If decl And (Not TFuncDeclList(decl) And declList.IsEmpty()) Return decl
  1735. If decl Then
  1736. declList.AddLast(decl)
  1737. End If
  1738. cdecl=cdecl.superClass
  1739. If maxSearchDepth < SCOPE_CLASS_HEIRARCHY Then
  1740. Exit
  1741. End If
  1742. Wend
  1743. Return declList
  1744. End Method
  1745. 'needs this 'coz you can't go blah.Super.GetDecl()...
  1746. Method GetDeclList2:Object( ident$, declList:TFuncDeclList = Null, maxSearchDepth:Int )
  1747. Return Super.GetDeclList( ident, declList, maxSearchDepth )
  1748. End Method
  1749. Method FindFuncDecl:TFuncDecl( ident$,args:TExpr[] = Null ,explicit:Int=False, isArg:Int = False, isIdentExpr:Int = False, throwOnNotMatched:Int = False, maxSearchDepth:Int )
  1750. ' try the super first...
  1751. Local funcDecl:TFuncDecl = Super.FindFuncDecl(ident, args, explicit, isArg, isIdentExpr, throwOnNotMatched, maxSearchDepth)
  1752. If funcDecl Then
  1753. Return funcDecl
  1754. End If
  1755. If args = Null Then
  1756. args = New TExpr[0]
  1757. End If
  1758. If Not IsInterface()
  1759. ' try getdecl first&
  1760. Local decl:TFuncDecl = TFuncDecl(GetDecl(ident))
  1761. If decl Then
  1762. Return decl
  1763. End If
  1764. Return FindFuncDecl2( ident,args,explicit,isIdentExpr )
  1765. EndIf
  1766. Local fdecl:TFuncDecl=FindFuncDecl2( ident,args,True )
  1767. For Local iface:TClassDecl=EachIn implmentsAll
  1768. Local decl:TFuncDecl=iface.FindFuncDecl2( ident,args,True )
  1769. If Not decl Continue
  1770. If fdecl
  1771. If fdecl.EqualsFunc( decl ) Continue
  1772. Err "Unable to determine overload to use: "+fdecl.ToString()+" or "+decl.ToString()+"."
  1773. EndIf
  1774. fdecl=decl
  1775. Next
  1776. If fdecl Or explicit Return fdecl
  1777. fdecl=FindFuncDecl2( ident,args,False )
  1778. For Local iface:TClassDecl=EachIn implmentsAll
  1779. Local decl:TFuncDecl=iface.FindFuncDecl2( ident,args,False )
  1780. If Not decl Continue
  1781. If fdecl
  1782. If fdecl.EqualsFunc( decl ) Continue
  1783. Err "Unable to determine overload to use: "+fdecl.ToString()+" or "+decl.ToString()+"."
  1784. EndIf
  1785. fdecl=decl
  1786. Next
  1787. Return fdecl
  1788. End Method
  1789. Method FindFuncDecl2:TFuncDecl( ident$,args:TExpr[],explicit:Int, isIdentExpr:Int = False )
  1790. Return Super.FindFuncDecl( ident,args,explicit,,isIdentExpr,0,0 )
  1791. End Method
  1792. Method GetAllFuncDecls:TFuncDecl[](funcs:TFuncDecl[] = Null, includeSuper:Int = True)
  1793. If Not funcs Then
  1794. funcs = New TFuncDecl[0]
  1795. End If
  1796. If superClass And includeSuper Then
  1797. funcs = superClass.GetAllFuncDecls(funcs)
  1798. End If
  1799. ' interface methods
  1800. For Local iface:TClassDecl=EachIn implmentsAll
  1801. funcs = iface.GetAllFuncDecls(funcs)
  1802. Next
  1803. For Local func:TFuncDecl = EachIn _decls
  1804. Local matched:Int = False
  1805. For Local i:Int = 0 Until funcs.length
  1806. ' found a match - we are overriding it
  1807. If func.IdentLower() = funcs[i].IdentLower() And func.EqualsArgs(funcs[i]) Then
  1808. matched = True
  1809. ' set this to our own func
  1810. funcs[i] = func
  1811. Exit
  1812. End If
  1813. Next
  1814. If Not matched Then
  1815. funcs :+ [func]
  1816. End If
  1817. Next
  1818. Return funcs
  1819. End Method
  1820. ' returns a list of original function decls (i.e. decls in the scope of their original declarations).
  1821. ' this is useful for generating vtables for extern types
  1822. Method GetAllOriginalFuncDecls:TFuncDecl[](funcs:TFuncDecl[] = Null, includeSuper:Int = True)
  1823. If Not funcs Then
  1824. funcs = New TFuncDecl[0]
  1825. End If
  1826. If superClass And includeSuper Then
  1827. funcs = superClass.GetAllOriginalFuncDecls(funcs, True)
  1828. End If
  1829. ' interface methods
  1830. For Local iface:TClassDecl=EachIn implmentsAll
  1831. For Local func:TFuncDecl=EachIn iface._decls
  1832. Local matched:Int = False
  1833. ' For Local i:Int = 0 Until funcs.length
  1834. ' ' found a match - we are overriding it
  1835. ' If func.IdentLower() = funcs[i].IdentLower() Then
  1836. ' matched = True
  1837. ' Exit
  1838. ' End If
  1839. ' Next
  1840. If Not matched Then
  1841. funcs :+ [func]
  1842. End If
  1843. Next
  1844. Next
  1845. For Local func:TFuncDecl = EachIn _decls
  1846. Local matched:Int = False
  1847. ' dont count any that are already in the funcs list
  1848. For Local i:Int = 0 Until funcs.length
  1849. ' found a match - we are overriding it
  1850. If func.IdentLower() = funcs[i].IdentLower() And func.EqualsArgs(funcs[i]) Then
  1851. matched = True
  1852. ' set this to our own func
  1853. 'funcs[i] = func
  1854. Exit
  1855. End If
  1856. Next
  1857. If Not matched Then
  1858. funcs :+ [func]
  1859. End If
  1860. Next
  1861. Return funcs
  1862. End Method
  1863. Method ExtendsClass:Int( cdecl:TClassDecl )
  1864. 'If Self=nullObjectClass Return True
  1865. ' If cdecl.IsTemplateArg()
  1866. ' cdecl=TType.objectType.FindClass()
  1867. ' EndIf
  1868. Local tdecl_:TClassDecl=Self
  1869. While tdecl_
  1870. If tdecl_=cdecl Return True
  1871. If cdecl.IsInterface()
  1872. For Local iface:TClassDecl=EachIn tdecl_.implmentsAll
  1873. If iface=cdecl Return True
  1874. Next
  1875. EndIf
  1876. tdecl_=tdecl_.superClass
  1877. Wend
  1878. Return False
  1879. End Method
  1880. Method OnSemant()
  1881. PushEnv Self
  1882. 'If Not IsTemplateInst()
  1883. ' For Local i:Int=0 Until args.Length
  1884. ' InsertDecl args[i]
  1885. ' args[i].Semant
  1886. ' Next
  1887. 'EndIf
  1888. 'Semant superclass
  1889. If superTy
  1890. 'superClass=superTy.FindClass()
  1891. superClass=superTy.SemantClass()
  1892. If superClass.IsInterface() Then
  1893. If Not IsExtern() Or Not superClass.IsExtern() Err superClass.ToString()+" is an interface, not a class."
  1894. If (IsExtern() And Not superClass.IsExtern()) Or (superClass.IsExtern() And Not IsExtern()) Err "Extern and non extern types cannot be mixed."
  1895. End If
  1896. If superClass.IsFinal() Err "Final types cannot be extended."
  1897. EndIf
  1898. 'Semant implemented interfaces
  1899. Local impls:TClassDecl[]=New TClassDecl[impltys.Length]
  1900. Local implsall:TStack=New TStack
  1901. For Local i:Int=0 Until impltys.Length
  1902. Local cdecl:TClassDecl=impltys[i].SemantClass()
  1903. If Not cdecl.IsInterface()
  1904. Err cdecl.ToString()+" is a type, not an interface."
  1905. EndIf
  1906. For Local j:Int=0 Until i
  1907. If impls[j]=cdecl
  1908. Err "Duplicate interface "+cdecl.ToString()+"."
  1909. EndIf
  1910. Next
  1911. impls[i]=cdecl
  1912. implsall.Push cdecl
  1913. For Local tdecl_:TDecl=EachIn cdecl.implmentsAll
  1914. implsall.Push tdecl_
  1915. Next
  1916. Next
  1917. Local length:Int = implsall.Length()
  1918. implmentsAll=New TClassDecl[length]
  1919. For Local i:Int=0 Until length
  1920. implmentsAll[i]=TClassDecl(implsall.Get(length - i - 1))
  1921. Next
  1922. implments=impls
  1923. Rem
  1924. If IsInterface()
  1925. 'add implemented methods to our methods
  1926. For Local iface:=EachIn implmentsAll
  1927. For Local decl:=EachIn iface.FuncDecls
  1928. InsertAlias decl.ident,decl
  1929. Next
  1930. Next
  1931. EndIf
  1932. EndRem
  1933. ' attrs|=DECL_SEMANTED
  1934. PopEnv
  1935. 'If IsTemplateArg()
  1936. ' actual=TType.objectType.FindClass()
  1937. ' Return
  1938. 'EndIf
  1939. 'If IsTemplateInst()
  1940. ' Return
  1941. 'EndIf
  1942. 'Are we abstract?
  1943. If Not IsAbstract()
  1944. For Local decl:TDecl=EachIn _decls
  1945. Local fdecl:TFuncDecl=TFuncDecl( decl )
  1946. If fdecl And fdecl.IsAbstract()
  1947. attrs:|DECL_ABSTRACT
  1948. Exit
  1949. EndIf
  1950. Next
  1951. EndIf
  1952. If Not lastOffset And superClass Then
  1953. lastOffset = superClass.LastOffset
  1954. End If
  1955. For Local decl:TFieldDecl=EachIn _decls
  1956. GetFieldOffset(decl)
  1957. Next
  1958. If Not IsExtern() And Not IsInterface()
  1959. Local fdecl:TFuncDecl
  1960. For Local decl:TFuncDecl=EachIn FuncDecls()
  1961. If Not decl.IsCtor() Continue
  1962. Local nargs:Int
  1963. For Local arg:TArgDecl=EachIn decl.argDecls
  1964. If Not arg.init nargs:+1
  1965. Next
  1966. If nargs Continue
  1967. fdecl=decl
  1968. Exit
  1969. Next
  1970. ' Don't need default new?
  1971. 'If Not fdecl
  1972. ' fdecl=New TFuncDecl.CreateF( "new",New TObjectType.Create( Self ),Null,FUNC_CTOR )
  1973. ' fdecl.AddStmt New TReturnStmt.Create( Null )
  1974. ' InsertDecl fdecl
  1975. 'EndIf
  1976. EndIf
  1977. 'NOTE: do this AFTER super semant so UpdateAttrs order is cool.
  1978. If AppScope() Then
  1979. AppScope().semantedClasses.AddLast Self
  1980. End If
  1981. End Method
  1982. Method SemantParts()
  1983. ' If IsSemanted() Return
  1984. ' Super.Semant()
  1985. For Local decl:TConstDecl = EachIn Decls()
  1986. decl.Semant()
  1987. Next
  1988. For Local decl:TGlobalDecl = EachIn Decls()
  1989. decl.Semant()
  1990. Next
  1991. ' NOTE : we can't semant functions here as they cause cyclic errors.
  1992. For Local decl:TFuncDecl = EachIn Decls()
  1993. decl.Semant()
  1994. Next
  1995. For Local decl:TFieldDecl = EachIn Decls()
  1996. decl.Semant()
  1997. Next
  1998. End Method
  1999. 'Ok, this dodgy looking beast 'resurrects' methods that may not currently be alive, but override methods that ARE.
  2000. Method UpdateLiveMethods:Int()
  2001. If IsInterface() Return 0
  2002. If Not superClass Return 0
  2003. Local n:Int
  2004. For Local decl:TFuncDecl=EachIn MethodDecls()
  2005. If decl.IsSemanted() Continue
  2006. Local live:Int
  2007. Local unsem:TList=New TList'<TFuncDecl>
  2008. unsem.AddLast decl
  2009. Local sclass:TClassDecl=superClass
  2010. While sclass
  2011. For Local decl2:TFuncDecl=EachIn sclass.MethodDecls( decl.ident )
  2012. If decl2.IsSemanted()
  2013. live=True
  2014. Else
  2015. unsem.AddLast decl2
  2016. If decl2.IsExtern() live=True
  2017. If decl2.actual.IsSemanted() live=True
  2018. EndIf
  2019. Next
  2020. sclass=sclass.superClass
  2021. Wend
  2022. If Not live
  2023. Local cdecl:TClassDecl=Self
  2024. While cdecl
  2025. For Local iface:TClassDecl=EachIn cdecl.implmentsAll
  2026. For Local decl2:TFuncDecl=EachIn iface.MethodDecls( decl.ident )
  2027. If decl2.IsSemanted()
  2028. live=True
  2029. Else
  2030. unsem.AddLast decl2
  2031. If decl2.IsExtern() live=True
  2032. If decl2.actual.IsSemanted() live=True
  2033. EndIf
  2034. Next
  2035. Next
  2036. cdecl=cdecl.superClass
  2037. Wend
  2038. EndIf
  2039. If Not live Continue
  2040. For Local decl:TDecl=EachIn unsem
  2041. decl.Semant
  2042. n:+1
  2043. Next
  2044. Next
  2045. Return n
  2046. End Method
  2047. Method FinalizeClass()
  2048. SemantParts()
  2049. PushErr errInfo
  2050. If Not IsInterface()
  2051. '
  2052. 'check for duplicate fields! - BlitzMax supports fields with the same name in subclasses..
  2053. '
  2054. 'For Local decl:TDecl=EachIn Semanted()
  2055. ' Local fdecl:TFieldDecl=TFieldDecl( decl )
  2056. ' If Not fdecl Continue
  2057. ' Local cdecl:TClassDecl=superClass
  2058. ' While cdecl
  2059. ' For Local decl:TDecl=EachIn cdecl.Semanted()
  2060. ' If decl.ident=fdecl.ident Err "Field '"+fdecl.ident+"' in class "+ToString()+" overrides existing declaration in class "+cdecl.ToString()
  2061. ' Next
  2062. ' cdecl=cdecl.superClass
  2063. ' Wend
  2064. 'Next
  2065. '
  2066. 'Check we implement all abstract methods!
  2067. '
  2068. If IsInstanced()
  2069. Local cdecl:TClassDecl=Self
  2070. Local impls:TList=New TList'<TFuncDecl>
  2071. While cdecl
  2072. For Local decl:TFuncDecl=EachIn cdecl.SemantedMethods()
  2073. If decl.IsAbstract()
  2074. Local found:Int
  2075. For Local decl2:TFuncDecl=EachIn impls
  2076. If decl.IdentLower() = decl2.IdentLower() And decl2.EqualsFunc( decl )
  2077. found=True
  2078. Exit
  2079. EndIf
  2080. Next
  2081. If Not found
  2082. Err "Can't create instance of type "+ToString()+" due to abstract method "+decl.ToString()+"."
  2083. EndIf
  2084. Else
  2085. impls.AddLast decl
  2086. EndIf
  2087. Next
  2088. cdecl=cdecl.superClass
  2089. Wend
  2090. EndIf
  2091. '
  2092. 'Check we implement all interface methods!
  2093. '
  2094. If Not IsAbstract() Then
  2095. Local ints:TMap = GetInterfaces()
  2096. For Local iface:TClassDecl=EachIn ints.Values()
  2097. If (Not IsExtern() And iface.IsExtern()) Or (IsExtern() And Not iface.IsExtern()) Then
  2098. Err "Cannot mix Extern and non Extern Types and Interfaces."
  2099. End If
  2100. For Local decl:TFuncDecl=EachIn iface.SemantedMethods()
  2101. Local found:Int
  2102. Local cdecl:TClassDecl=Self
  2103. While cdecl And Not found
  2104. For Local decl2:TFuncDecl=EachIn cdecl.SemantedMethods( decl.ident )
  2105. If decl.EqualsFunc( decl2 )
  2106. found=True
  2107. Exit
  2108. EndIf
  2109. Next
  2110. cdecl = cdecl.superClass
  2111. Wend
  2112. If Not found
  2113. Err decl.ToString() + " must be implemented by type " + ToString()
  2114. EndIf
  2115. Next
  2116. Next
  2117. End If
  2118. EndIf
  2119. PopErr
  2120. End Method
  2121. Method GetFieldOffset(decl:TFieldDecl)
  2122. Local ty:TType = decl.declTy
  2123. Local modifier:Int = POINTER_SIZE
  2124. If TIntType(ty) Or TFloatType(ty) Or TUIntType(ty) Then
  2125. modifier = 4
  2126. Else If TShortType(ty) Then
  2127. modifier = 2
  2128. Else If TLongType(ty) Or TDoubleType(ty) Or TULongType(ty) Then
  2129. modifier = 8
  2130. Else If TByteType(ty) Then
  2131. modifier = 1
  2132. Else If TSizeTType(ty) Then
  2133. modifier = WORD_SIZE
  2134. End If
  2135. If modifier > 1 And lastOffset Mod modifier Then
  2136. lastOffset :+ modifier - (lastOffset Mod modifier)
  2137. End If
  2138. decl.offset = lastOffset
  2139. lastOffset :+ modifier
  2140. End Method
  2141. ' returns a map of all interfaces implemented in this hierarchy
  2142. Method GetInterfaces:TMap(map:TMap = Null)
  2143. If Not map Then
  2144. map = New TMap
  2145. End If
  2146. For Local iface:TClassDecl=EachIn implmentsAll
  2147. If iface.IsInterface() Then
  2148. Local cdecl:TClassDecl = iface
  2149. While cdecl
  2150. If cdecl.IsInterface() Then
  2151. If Not map.Contains(cdecl) Then
  2152. map.Insert(cdecl, cdecl)
  2153. End If
  2154. End If
  2155. cdecl=cdecl.superClass
  2156. Wend
  2157. End If
  2158. Next
  2159. If superClass Then
  2160. map = superClass.GetInterfaces(map)
  2161. End If
  2162. Return map
  2163. End Method
  2164. Method GetImplementedFuncs:TList(list:TList = Null)
  2165. If Not list Then
  2166. list = New TList
  2167. End If
  2168. For Local idecl:TClassDecl = EachIn implmentsAll
  2169. idecl.GetImplementedFuncs(list)
  2170. Next
  2171. For Local decl:TFuncDecl = EachIn SemantedMethods()
  2172. list.AddLast(decl)
  2173. Next
  2174. Return list
  2175. End Method
  2176. End Type
  2177. Type TLoopLabelDecl Extends TDecl
  2178. Field realIdent:String
  2179. Method Create:TLoopLabelDecl( ident$, attrs:Int=0 )
  2180. Self.ident="#" + ident
  2181. Self.realIdent = ident
  2182. Self.attrs=attrs
  2183. Return Self
  2184. End Method
  2185. Method OnCopy:TDecl(deep:Int = True)
  2186. Return New TLoopLabelDecl.Create( realIdent,attrs )
  2187. End Method
  2188. Method OnSemant()
  2189. End Method
  2190. End Type
  2191. Type TDataLabelDecl Extends TDecl
  2192. Field realIdent:String
  2193. Field index:Int
  2194. Method Create:TDataLabelDecl( ident$, attrs:Int=0 )
  2195. Self.ident="#" + ident
  2196. Self.realIdent = ident
  2197. Self.attrs=attrs
  2198. Return Self
  2199. End Method
  2200. Method OnCopy:TDecl(deep:Int = True)
  2201. Return New TDataLabelDecl.Create( realIdent,attrs )
  2202. End Method
  2203. Method OnSemant()
  2204. End Method
  2205. End Type
  2206. Type TDefDataDecl Extends TDecl
  2207. Global count:Int
  2208. Field label:TDataLabelDecl
  2209. Field data:TExpr[]
  2210. Method Create:TDefDataDecl(data:TExpr[], label:TDataLabelDecl = Null, attrs:Int=0 )
  2211. Self.data=data
  2212. Self.label=label
  2213. Self.attrs=attrs
  2214. Return Self
  2215. End Method
  2216. Method OnCopy:TDecl(deep:Int = True)
  2217. Return New TDefDataDecl.Create(TExpr.CopyArgs(data),TDataLabelDecl(label.Copy()),attrs)
  2218. End Method
  2219. Method OnSemant()
  2220. If data Then
  2221. If label Then
  2222. label.index = count
  2223. End If
  2224. For Local i:Int = 0 Until data.length
  2225. data[i] = data[i].Semant()
  2226. If Not TConstExpr(data[i]) Then
  2227. Err "Data items must be numeric or strings"
  2228. Else
  2229. ' todo : more type tests?
  2230. End If
  2231. count :+ 1
  2232. Next
  2233. Else
  2234. ' err?
  2235. End If
  2236. End Method
  2237. End Type
  2238. Const MODULE_STRICT:Int=1
  2239. Const MODULE_SUPERSTRICT:Int=2
  2240. Const MODULE_ACTUALMOD:Int=4
  2241. Type TNamespaceDecl Extends TScopeDecl
  2242. ' Field mods:TMap = New TMap
  2243. Method Create:TNamespaceDecl( ident$,munged$ )
  2244. Self.ident=ident
  2245. Self.munged=munged
  2246. Return Self
  2247. End Method
  2248. ' Method GetDecl:Object( ident$ )
  2249. ' Return mods.ValueForKey(ident.ToLower())
  2250. ' End Method
  2251. End Type
  2252. Type TModuleDecl Extends TScopeDecl
  2253. Field filepath$
  2254. Field relpath$
  2255. Field imported:TUnorderedMap=New TUnorderedMap'<TModuleDecl> 'Maps filepath to modules
  2256. Field pubImported:TUnorderedMap =New TUnorderedMap'<TModuleDecl> 'Ditto for publicly imported modules
  2257. Field pmod:TModuleDecl
  2258. Field fileImports:TList=New TList'StringList
  2259. ' cache of ModuleInfo lines
  2260. Field modInfo:TList = New TList
  2261. Field _getDeclTreeCache:TList
  2262. Field _getDeclCache:TMap = New TMap
  2263. Field _getDeclListCache:TMap = New TMap
  2264. Method ToString$()
  2265. Return "Module "+munged
  2266. End Method
  2267. Method Create:TModuleDecl( ident$,munged$,filepath$,attrs:Int )
  2268. Self.ident=ident
  2269. Self.munged=munged
  2270. Self.filepath=filepath
  2271. Self.attrs=attrs
  2272. If ident.Find(".") <> -1 Then
  2273. Local m:String = ident[..ident.Find(".")]
  2274. Local ns:TNamespaceDecl = TNamespaceDecl(_appInstance.GetDecl(m.ToLower()))
  2275. If Not ns Then
  2276. ns = New TNamespaceDecl.Create(m, m)
  2277. If _appInstance.mainModule Then
  2278. _appInstance.mainModule.InsertDecl(ns)
  2279. Else
  2280. ' this must be the main module...
  2281. InsertDecl(ns)
  2282. End If
  2283. End If
  2284. ns.InsertDecl(Self)
  2285. End If
  2286. Return Self
  2287. End Method
  2288. Method UpdateFilePath(fp:String)
  2289. filepath = fp
  2290. End Method
  2291. Method AddImport(imp:String, obj:Object)
  2292. imported.Insert(imp, obj)
  2293. FlushCaches()
  2294. End Method
  2295. Method FlushCaches()
  2296. _getDeclTreeCache = Null
  2297. If TModuleDecl(pmod) Then
  2298. TModuleDecl(pmod).FlushCaches()
  2299. End If
  2300. End Method
  2301. Method IsStrict:Int()
  2302. Return (attrs & MODULE_STRICT)<>0
  2303. End Method
  2304. Method IsSuperStrict:Int()
  2305. Return (attrs & MODULE_SUPERSTRICT)<>0
  2306. End Method
  2307. Method IsActualModule:Int()
  2308. Return (attrs & MODULE_ACTUALMOD)<>0
  2309. End Method
  2310. Method GetDecl:Object( ident$ )
  2311. ' if we previously found it, return it from the cache
  2312. Local decl:Object = _getDeclCache.ValueForKey(ident)
  2313. If decl Then
  2314. Return decl
  2315. End If
  2316. If _getDeclTreeCache Then
  2317. Local declmod$
  2318. For Local mdecl:TModuleDecl = EachIn _getDeclTreeCache
  2319. If ident = mdecl.ident
  2320. _getDeclCache.Insert(ident, mdecl)
  2321. Return mdecl
  2322. End If
  2323. Local tdecl_:Object=mdecl.GetDecl2( ident )
  2324. If tdecl_ And tdecl_<>decl
  2325. If mdecl=Self
  2326. _getDeclCache.Insert(ident, tdecl_)
  2327. Return tdecl_
  2328. End If
  2329. If decl
  2330. Err "Duplicate identifier '"+ident+"' found in module '"+declmod+"' and module '"+mdecl.ident+"'."
  2331. EndIf
  2332. decl=tdecl_
  2333. declmod=mdecl.ident
  2334. EndIf
  2335. Next
  2336. Else
  2337. _getDeclTreeCache = New TList
  2338. Local todo:TList=New TList'<TModuleDecl>
  2339. 'Local done:TIntMap=New TIntMap'<TModuleDecl>
  2340. Local done:TMap = New TMap
  2341. todo.AddLast Self
  2342. 'done.Insert _filePathId,Self
  2343. done.Insert filePath,Self
  2344. Local declmod$
  2345. While Not todo.IsEmpty()
  2346. Local mdecl:TModuleDecl=TModuleDecl(todo.RemoveLast())
  2347. _getDeclTreeCache.AddLast(mdecl)
  2348. Local imps:TUnorderedMap=mdecl.imported
  2349. For Local mdecl2:TModuleDecl=EachIn imps.Values()
  2350. 'If Not done.Contains( mdecl2._filePathId )
  2351. If Not done.Contains( mdecl2.filePath )
  2352. todo.AddLast mdecl2
  2353. 'done.Insert mdecl2._filePathId,mdecl2
  2354. done.Insert mdecl2.filePath,mdecl2
  2355. EndIf
  2356. Next
  2357. Wend
  2358. Return GetDecl(ident)
  2359. End If
  2360. ' cache it for next time
  2361. _getDeclCache.Insert(ident, decl)
  2362. Return decl
  2363. End Method
  2364. Method GetDecl2:Object( ident$ )
  2365. Return Super.GetDecl( ident )
  2366. End Method
  2367. Method GetDeclList:Object( ident$, declList:TFuncDeclList = Null, maxSearchDepth:Int )
  2368. If Not declList Then
  2369. declList = New TFuncDeclList
  2370. End If
  2371. Local decl:Object,declmod$
  2372. If _getDeclTreeCache Then
  2373. ' Print " Using Cache"
  2374. Local declmod$
  2375. For Local mdecl:TModuleDecl = EachIn _getDeclTreeCache
  2376. If ident = mdecl.ident
  2377. '_getDeclCache.Insert(identId, mdecl)
  2378. Return mdecl
  2379. End If
  2380. Local tdecl_:Object=mdecl.GetDeclList2( ident, declList, maxSearchDepth )
  2381. If tdecl_ And tdecl_<>decl
  2382. If mdecl=Self
  2383. _getDeclCache.Insert(ident, tdecl_)
  2384. Return tdecl_
  2385. End If
  2386. If decl
  2387. Err "Duplicate identifier '"+ident+"' found in module '"+declmod+"' and module '"+mdecl.ident+"'."
  2388. EndIf
  2389. decl=tdecl_
  2390. declmod=mdecl.ident
  2391. EndIf
  2392. Next
  2393. Else
  2394. _getDeclTreeCache = New TList
  2395. Local todo:TList=New TList'<TModuleDecl>
  2396. Local done:TMap=New TMap'<TModuleDecl>
  2397. todo.AddLast Self
  2398. done.Insert filepath,Self
  2399. 'Local decl:Object,declmod$
  2400. While Not todo.IsEmpty()
  2401. Local mdecl:TModuleDecl=TModuleDecl(todo.RemoveLast())
  2402. _getDeclTreeCache.AddLast(mdecl)
  2403. Local imps:TUnorderedMap=mdecl.imported
  2404. For Local mdecl2:TModuleDecl=EachIn imps.Values()
  2405. If Not done.Contains( mdecl2.filepath )
  2406. todo.AddLast mdecl2
  2407. done.Insert mdecl2.filepath,mdecl2
  2408. EndIf
  2409. Next
  2410. Wend
  2411. Return GetDeclList( ident, declList, maxSearchDepth )
  2412. End If
  2413. Return decl
  2414. End Method
  2415. Method GetDeclList2:Object( ident$, declList:TFuncDeclList = Null, maxSearchDepth:Int )
  2416. Return Super.GetDeclList( ident, declList, maxSearchDepth )
  2417. End Method
  2418. Method OnSemant()
  2419. Local decl:TFuncDecl = FindFuncDecl( "__localmain", ,,,,,SCOPE_MODULE )
  2420. If decl Then
  2421. decl.Semant
  2422. End If
  2423. For Local gdecl:TGlobalDecl=EachIn _decls
  2424. gdecl.Semant
  2425. Next
  2426. For Local cdecl:TClassDecl=EachIn _decls
  2427. cdecl.Semant
  2428. Next
  2429. For Local fdecl:TFuncDecl=EachIn _decls
  2430. fdecl.Semant
  2431. Next
  2432. For Local cdecl:TConstDecl=EachIn _decls
  2433. cdecl.Semant
  2434. Next
  2435. End Method
  2436. End Type
  2437. Type TAppDecl Extends TScopeDecl
  2438. Field imported:TUnorderedMap=New TUnorderedMap'<TModuleDecl> 'maps modpath->mdecl
  2439. Field globalImports:TUnorderedMap = New TUnorderedMap
  2440. Field mainModule:TModuleDecl
  2441. Field mainFunc:TFuncDecl
  2442. Field semantedClasses:TList=New TList'<TClassDecl> 'in-order (ie: base before derived) list of _semanted classes
  2443. Field semantedGlobals:TList=New TList'<TGlobalDecl> 'in-order (ie: dependancy sorted) list of _semanted globals
  2444. Field fileImports:TList=New TList'StringList
  2445. Field headers:TList = New TList
  2446. Field stringConsts:TMap = New TMap
  2447. Field stringConstCount:Int
  2448. Field incbins:TList = New TList
  2449. Field genIncBinHeader:Int = False
  2450. Field dataDefs:TList = New TList
  2451. Field scopeDefs:TMap = New TMap
  2452. Method GetPathPrefix:String()
  2453. If opt_buildtype = BUILDTYPE_MODULE Then
  2454. Local prefix:String
  2455. Local path:String[] = mainModule.filepath.split("/")
  2456. Local c:Int = 0
  2457. For Local dir:String = EachIn path
  2458. If c Then
  2459. prefix :+ dir.Replace(".mod", "") + "_"
  2460. c:- 1
  2461. End If
  2462. If dir = "mod" Then
  2463. c = 2
  2464. End If
  2465. Next
  2466. Else
  2467. Return "bb_"
  2468. End If
  2469. End Method
  2470. Method InsertModule( mdecl:TModuleDecl )
  2471. mdecl.scope=Self
  2472. imported.Insert mdecl.filepath,mdecl
  2473. If Not mainModule
  2474. mainModule=mdecl
  2475. EndIf
  2476. End Method
  2477. Method IsImported:Int(modpath:String)
  2478. Return globalImports.Contains(modpath)
  2479. End Method
  2480. Method GetDecl:Object( ident$ )
  2481. Local obj:Object = Super.GetDecl(ident)
  2482. If Not obj And mainModule Then
  2483. Return mainModule.GetDecl(ident)
  2484. End If
  2485. Return obj
  2486. End Method
  2487. Method OnSemant()
  2488. 'DebugStop
  2489. _env=Null
  2490. pushenv Self
  2491. SemantDataDefs()
  2492. mainModule.Semant
  2493. mainFunc=mainModule.FindFuncDecl( "__localmain",,,,,,SCOPE_MODULE )
  2494. ' FIXME
  2495. If Not mainFunc Err "Function 'Main' not found."
  2496. SemantDecls()
  2497. Repeat
  2498. Local more:Int
  2499. For Local cdecl:TClassDecl=EachIn semantedClasses
  2500. more:+cdecl.UpdateLiveMethods()
  2501. Next
  2502. If Not more Exit
  2503. Forever
  2504. For Local cdecl:TClassDecl=EachIn semantedClasses
  2505. cdecl.FinalizeClass
  2506. Next
  2507. End Method
  2508. Method SemantDataDefs()
  2509. TDefDataDecl.count = 0
  2510. For Local decl:TDecl = EachIn dataDefs
  2511. decl.Semant
  2512. Next
  2513. End Method
  2514. Method SemantDecls()
  2515. For Local decl:TDecl=EachIn mainModule._decls
  2516. decl.Semant
  2517. ' consts
  2518. Local cdecl:TConstDecl=TConstDecl( decl )
  2519. If cdecl
  2520. cdecl.Semant()
  2521. Continue
  2522. End If
  2523. ' classes
  2524. Local tdecl:TClassDecl=TClassDecl( decl )
  2525. If tdecl
  2526. tdecl.Semant()
  2527. tdecl.SemantParts()
  2528. Continue
  2529. EndIf
  2530. ' functions
  2531. Local fdecl:TFuncDecl=TFuncDecl( decl )
  2532. If fdecl And fdecl <> _appInstance.mainFunc Then
  2533. fdecl.Semant()
  2534. Continue
  2535. End If
  2536. ' globals
  2537. Local gdecl:TGlobalDecl=TGlobalDecl( decl )
  2538. If gdecl
  2539. gdecl.Semant()
  2540. Continue
  2541. End If
  2542. Next
  2543. End Method
  2544. Method hasStringConst:Int(value:String)
  2545. Return stringConsts.ValueForKey(value) <> Null
  2546. End Method
  2547. Method mapStringConsts(value:String)
  2548. Local sc:TStringConst = TStringConst(stringConsts.ValueForKey(value))
  2549. If Not sc Then
  2550. Local sc:TStringConst = New TStringConst
  2551. sc.count = 1
  2552. If value Then
  2553. sc.id = "_s" + stringConstCount
  2554. Else
  2555. sc.id = "bbEmptyString"
  2556. End If
  2557. stringConsts.Insert(value, sc)
  2558. If value Then
  2559. stringConstCount:+ 1
  2560. End If
  2561. Else
  2562. sc.count :+ 1
  2563. End If
  2564. End Method
  2565. Method removeStringConst(value:String)
  2566. If value Then
  2567. Local sc:TStringConst = TStringConst(stringConsts.ValueForKey(value))
  2568. If sc Then
  2569. If sc.count > 0 Then
  2570. sc.count :- 1
  2571. 'stringConsts.Remove(value)
  2572. End If
  2573. End If
  2574. End If
  2575. End Method
  2576. Method FindDataLabel:TDecl(ident:String)
  2577. For Local dd:TDefDataDecl = EachIn dataDefs
  2578. If dd.label And dd.label.ident.ToLower() = ident.ToLower() Then
  2579. Return dd
  2580. End If
  2581. Next
  2582. End Method
  2583. End Type
  2584. Type TStringConst
  2585. Field id:String
  2586. Field count:Int
  2587. End Type