decl.bmx 99 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112
  1. ' Copyright (c) 2013-2019 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_READ_ONLY:Int= $000100
  29. Const DECL_OVERRIDE:Int= $40000000
  30. Const DECL_SEMANTED:Int= $100000
  31. Const DECL_SEMANTING:Int= $200000
  32. Const DECL_CYCLIC:Int= $8000000
  33. Const DECL_POINTER:Int= $400000
  34. Const DECL_ARG:Int= $800000
  35. Const DECL_INITONLY:Int= $1000000
  36. Const DECL_NODEBUG:Int= $2000000
  37. Const DECL_PROTECTED:Int= $4000000
  38. Const DECL_EXPORT:Int= $8000000
  39. Const DECL_API_CDECL:Int= $00000000
  40. Const DECL_API_STDCALL:Int= $10000000
  41. Const DECL_API_DEFAULT:Int=DECL_API_CDECL
  42. Const DECL_API_FLAGS:Int= DECL_API_CDECL | DECL_API_STDCALL
  43. Const DECL_NESTED:Int= $20000000
  44. Const CLASS_INTERFACE:Int= $002000
  45. Const CLASS_THROWABLE:Int= $004000
  46. Const CLASS_STRUCT:Int= $008000
  47. Const CLASS_GENERIC:Int= $001000
  48. Const CLASS_FLAGS:Int = CLASS_INTERFACE | CLASS_THROWABLE | CLASS_STRUCT | CLASS_GENERIC
  49. Const SCOPE_FUNC:Int = 0
  50. Const SCOPE_CLASS_LOCAL:Int = 1
  51. Const SCOPE_CLASS_HEIRARCHY:Int = 2
  52. Const SCOPE_MODULE:Int = 3
  53. Const SCOPE_ALL:Int = 4
  54. Const BLOCK_OTHER:Int = $000
  55. Const BLOCK_LOOP:Int = $001
  56. Const BLOCK_TRY:Int = $002
  57. Const BLOCK_CATCH:Int = $004
  58. Const BLOCK_FINALLY:Int = $008
  59. Const BLOCK_IF:Int = $010
  60. Const BLOCK_ELSE:Int = $020
  61. Const BLOCK_FUNCTION:Int = $040
  62. Const BLOCK_TRY_CATCH:Int = BLOCK_TRY | BLOCK_CATCH
  63. Const BLOCK_IF_ELSE:Int = BLOCK_IF | BLOCK_ELSE
  64. 'Const CALL_CONV_CDECL:Int = 0
  65. 'Const CALL_CONV_STDCALL:Int = 1
  66. 'Const CALL_CONV_DEFAULT:Int = CALL_CONV_CDECL
  67. Global _env:TScopeDecl
  68. Global _envStack:TList=New TList
  69. Global _appInstance:TAppDecl
  70. Global _loopnest:Int
  71. Function PushEnv( env:TScopeDecl )
  72. If _env _envStack.AddLast( _env )
  73. _env=env
  74. End Function
  75. Function PopEnv()
  76. _env=TScopeDecl( _envStack.RemoveLast() )
  77. End Function
  78. Type TFuncDeclList Extends TList
  79. Field ident:String
  80. Field _identLower:String
  81. Method IdentLower:String()
  82. If Not _identLower Then
  83. _identLower = ident.ToLower()
  84. End If
  85. Return _identLower
  86. End Method
  87. End Type
  88. Type TMetadata
  89. Field metadataString:String
  90. ' key/value pairs
  91. Field meta:TMap
  92. Method InsertMeta(key:String, value:String)
  93. If Not meta Then
  94. meta = New TMap
  95. End If
  96. meta.Insert(key, value)
  97. End Method
  98. Method HasMeta:Int(key:String)
  99. Return meta And meta.Contains(key.ToLower())
  100. End Method
  101. End Type
  102. Type TDecl
  103. Field ident$
  104. Field munged$
  105. Field errInfo$
  106. Field actual:TDecl
  107. Field scope:TScopeDecl
  108. Field attrs:Int
  109. Field metadata:TMetadata = New TMetadata
  110. Field declImported:Int = False
  111. Field generated:Int
  112. Field _identLower:String
  113. Method New()
  114. errInfo=_errInfo
  115. actual=Self
  116. End Method
  117. Method OnCopy:TDecl(deep:Int = True) Abstract
  118. Method IdentLower:String()
  119. If Not _identLower Then
  120. _identLower = ident.ToLower()
  121. End If
  122. Return _identLower
  123. End Method
  124. Method ToString$()
  125. If TClassDecl( scope ) Return scope.ToString()+"."+ident
  126. Return ident
  127. End Method
  128. Method ToTypeString:String()
  129. End Method
  130. Method IsExtern:Int()
  131. Return (attrs & DECL_EXTERN)<>0
  132. End Method
  133. Method IsFinal:Int()
  134. Return (attrs & DECL_FINAL)<>0
  135. End Method
  136. Method IsPrivate:Int()
  137. Return (attrs & DECL_PRIVATE)<>0
  138. End Method
  139. Method IsProtected:Int()
  140. Return (attrs & DECL_PROTECTED)<>0
  141. End Method
  142. Method IsPublic:Int()
  143. Return Not (IsPrivate() Or IsProtected())
  144. End Method
  145. Method IsReadOnly:Int()
  146. Return (attrs & DECL_READ_ONLY)<>0
  147. End Method
  148. Method IsAbstract:Int()
  149. Return (attrs & DECL_ABSTRACT)<>0
  150. End Method
  151. Method IsSemanted:Int()
  152. Return (attrs & DECL_SEMANTED)<>0
  153. End Method
  154. Method IsSemanting:Int()
  155. Return (attrs & DECL_SEMANTING)<>0
  156. End Method
  157. Method IsNoDebug:Int()
  158. Return (attrs & DECL_NODEBUG)<>0
  159. End Method
  160. Method FuncScope:TFuncDecl()
  161. If TFuncDecl( Self ) Return TFuncDecl( Self )
  162. If scope Return scope.FuncScope()
  163. End Method
  164. Method ClassScope:TClassDecl()
  165. If TClassDecl( Self ) Return TClassDecl( Self )
  166. If scope Return scope.ClassScope()
  167. End Method
  168. Method ModuleScope:TModuleDecl()
  169. If TModuleDecl( Self ) Return TModuleDecl( Self )
  170. ' "app" is a module container
  171. If TAppDecl( Self ) Return TAppDecl( Self).mainModule
  172. If scope Return scope.ModuleScope()
  173. End Method
  174. Method AppScope:TAppDecl()
  175. If TAppDecl( Self ) Return TAppDecl( Self )
  176. If scope Return scope.AppScope()
  177. End Method
  178. ' find an owning scope of function, class or module
  179. Method ParentScope:TScopeDecl()
  180. If scope Then
  181. ' func scope
  182. If TFuncDecl( scope ) Return TFuncDecl( scope )
  183. ' class scope
  184. If TClassDecl( scope ) Return TClassDecl( scope )
  185. ' module scope
  186. If TModuleDecl( scope ) Return TModuleDecl( scope )
  187. Return scope.ParentScope()
  188. End If
  189. End Method
  190. Method CheckAccess:Int()
  191. If IsPrivate() And ModuleScope()<>_env.ModuleScope() Return False
  192. Return True
  193. End Method
  194. Method AssertAccess()
  195. If Not CheckAccess()
  196. If IsPrivate() Then
  197. Err ToString() +" is private."
  198. Else
  199. Err ToString() +" is protected."
  200. End If
  201. EndIf
  202. End Method
  203. Method Copy:TDecl(deep:Int = True)
  204. Local t:TDecl=OnCopy(deep)
  205. t.munged=munged
  206. t.errInfo=errInfo
  207. Return t
  208. End Method
  209. Method Semant()
  210. If IsSemanted() Return
  211. If IsSemanting() Then
  212. If attrs & DECL_CYCLIC Then
  213. Return
  214. End If
  215. Err "Cyclic declaration of '"+ident+"'."
  216. End If
  217. If actual<>Self
  218. actual.Semant
  219. EndIf
  220. PushErr errInfo
  221. If scope
  222. PushEnv scope
  223. EndIf
  224. attrs:|DECL_SEMANTING
  225. 'If ident And ClassScope() Print "Semanting "+ToString()
  226. OnSemant
  227. attrs:&~DECL_SEMANTING
  228. attrs:|DECL_SEMANTED
  229. If scope
  230. 'If Not IsExtern()
  231. If TFuncDecl(Self) And attrs & FUNC_PTR
  232. 'DebugLog "**** " + ident
  233. Else
  234. ' a nested function/class needs to be scoped to another function, class or module.
  235. If attrs & FUNC_NESTED Or attrs & DECL_NESTED Then
  236. Local sc:TScopeDecl = ParentScope()
  237. ' if our scope isn't one of the above, let it be so.
  238. If sc <> scope Then
  239. scope = Null
  240. sc.InsertDecl(Self)
  241. End If
  242. End If
  243. scope._semanted.AddLast Self
  244. If TGlobalDecl( Self )
  245. ' FIXME
  246. If AppScope() Then
  247. AppScope().semantedGlobals.AddLast TGlobalDecl( Self )
  248. End If
  249. EndIf
  250. If TModuleDecl( scope )
  251. ' FIXME
  252. Local app:TAppDecl = AppScope()
  253. If app Then
  254. app._semanted.AddLast Self
  255. End If
  256. EndIf
  257. EndIf
  258. If TValDecl(Self) And TValDecl(Self).deferInit Then
  259. TValDecl(Self).SemantInit
  260. End If
  261. PopEnv
  262. Else
  263. If TValDecl(Self) And TValDecl(Self).deferInit Then
  264. TValDecl(Self).SemantInit
  265. End If
  266. EndIf
  267. PopErr
  268. End Method
  269. Method InitInstance:TDecl( decl:TDecl )
  270. decl.ident=ident
  271. decl.munged=munged
  272. decl.errInfo=errInfo
  273. decl.actual=actual
  274. decl.scope=Null
  275. decl.attrs=attrs & ~(DECL_SEMANTED|DECL_SEMANTING)
  276. Return decl
  277. End Method
  278. Method GenInstance:TDecl()
  279. InternalErr "TDecl.GenInstance"
  280. End Method
  281. Method OnSemant() Abstract
  282. Method Clear()
  283. End Method
  284. End Type
  285. Type TValDecl Extends TDecl
  286. 'pre-semant
  287. Field declTy:TType
  288. Field declInit:TExpr
  289. 'post-semant
  290. Field ty:TType
  291. Field init:TExpr
  292. Field deferInit:Int = False
  293. Method ToString$()
  294. Local t$=Super.ToString()
  295. If ty Return t+":"+ty.ToString()
  296. If declTy Return t+":"+declTy.ToString()
  297. Return t+":?"
  298. End Method
  299. Method ToTypeString:String()
  300. If ty Return ty.ToString()
  301. If declTy Return declTy.ToString()
  302. End Method
  303. Method CopyInit:TExpr()
  304. If init Return init.Copy()
  305. End Method
  306. Method OnSemant()
  307. 'DebugStop
  308. If declTy
  309. Local at:TType = TArrayType(declTy)
  310. While TArrayType(at)
  311. at = TArrayType(at).elemType
  312. Wend
  313. ' ensure to set the scope for a function pointer array before semanting
  314. If TFunctionPtrType(at) Then
  315. If Not TFunctionPtrType(at).func.scope Then
  316. If scope Then
  317. TFunctionPtrType(at).func.scope = scope
  318. Else
  319. TFunctionPtrType(at).func.scope = _env
  320. End If
  321. End If
  322. End If
  323. ' pass the scope into the function ptr
  324. If TFunctionPtrType(declTy) Then
  325. If Not TFunctionPtrType(declTy).func.scope Then
  326. If scope Then
  327. TFunctionPtrType(declTy).func.scope = scope
  328. Else
  329. TFunctionPtrType(declTy).func.scope = _env
  330. End If
  331. End If
  332. End If
  333. ty=declTy.Semant()
  334. If Not deferInit Then
  335. SemantInit()
  336. End If
  337. Else If declInit
  338. If Not deferInit Then
  339. SemantInit()
  340. End If
  341. Else
  342. InternalErr "TValDecl.OnSemant"
  343. EndIf
  344. End Method
  345. Method SemantInit()
  346. ' for field initialisation, create a stub New() method to use as current scope
  347. ' since fields are initialised in New(). Otherwise the scope would be "class", which is
  348. ' incorrect for processing field inits.
  349. If TFieldDecl(Self) And declInit Then
  350. Local newScope:TFuncDecl = New TFuncDecl.CreateF( "new", Null,Null,FUNC_METHOD )
  351. newScope.scope = _env
  352. PushEnv(newScope)
  353. End If
  354. If declTy
  355. If declInit Then
  356. If TFunctionPtrType(ty) Then
  357. Local expr:TExpr
  358. If TInvokeExpr(declInit) Then
  359. expr = declInit.Copy()
  360. Else If TConstExpr(declInit) Then
  361. expr = declInit.Copy().Semant()
  362. Else If TFuncCallExpr(declInit) Then
  363. expr=declInit.Copy().Semant()
  364. Else If TNullExpr(declInit) Then
  365. expr = declInit
  366. Else
  367. ' declInit can only be an expression, never a statement
  368. ' this means that any function call in there is required to have parentheses, and will
  369. ' thus appear in the form of a TFuncCallExpr
  370. ' as such, trying SemantFunc in the Else branch seems pointless and will in fact wrongly
  371. ' interpret function pointers (as TIdentExpr, TIndexExpr, possibly others?) as calls
  372. Rem
  373. Local argExpr:TExpr[] = New TExpr[0]
  374. For Local arg:TArgDecl = EachIn TFunctionPtrType(ty).func.argDecls
  375. Local ldecl:TLocalDecl = New TLocalDecl.Create(arg.ident, arg.declTy, Null, 0)
  376. ldecl.Semant()
  377. Local aexp:TVarExpr = New TVarExpr.Create(ldecl)
  378. 'Local aexp:TIdentTypeExpr = New TIdentTypeExpr.Create(arg.declTy)
  379. aexp.Semant()
  380. argExpr :+ [aexp]
  381. Next
  382. expr=declInit.Copy().SemantFunc(argExpr, False, False)
  383. If Not expr Then
  384. expr = declInit.Copy().Semant()
  385. End If
  386. End Rem
  387. expr = declInit.Copy().Semant()
  388. End If
  389. If expr.exprType.EqualsType( ty ) Then
  390. init = expr
  391. Else
  392. init = New TCastExpr.Create( ty,expr,CAST_EXPLICIT ).Semant()
  393. End If
  394. Else
  395. If TArrayExpr(declInit) And TArrayType(ty) And TNumericType(TArrayType(ty).elemType) Then
  396. TArrayExpr(declInit).toType = TArrayType(ty).elemType
  397. End If
  398. init=declInit.Copy().SemantAndCast(ty)
  399. ' check if struct has been initialised
  400. If TObjectType(ty) And TObjectType(ty).classDecl.IsStruct() Then
  401. ' new not used
  402. If TConstExpr(init) And Not TConstExpr(init).value Then
  403. Local found:Int = False
  404. ' struct contains any objects?
  405. For Local fld:TFieldDecl = EachIn TObjectType(ty).classDecl._decls
  406. If Not fld.IsSemanted() Then
  407. fld.Semant()
  408. End If
  409. If TObjectType(fld.ty) Or TStringType(fld.ty) Or TArrayType(fld.ty) Then
  410. found = True
  411. Exit
  412. End If
  413. Next
  414. ' we need to initialise object fields, so we'll call the default constructor
  415. If found Then
  416. init = New TNewObjectExpr.Create(ty, Null).Semant()
  417. End If
  418. End If
  419. End If
  420. End If
  421. End If
  422. Else If declInit
  423. init=declInit.Copy().Semant()
  424. ty=init.exprType
  425. End If
  426. If init Then
  427. If TVarExpr(init) And TVarExpr(init).decl = Self Then
  428. Err "Identifier '" + TVarExpr(init).decl.ident + "' not found."
  429. End If
  430. If TNewObjectExpr(init) And TVarExpr(TNewObjectExpr(init).instanceExpr) And TVarExpr(TNewObjectExpr(init).instanceExpr).decl = Self Then
  431. Err "Identifier '" + Self.ident + "' not found."
  432. End If
  433. End If
  434. ' remove the temporary scope
  435. If TFieldDecl(Self) And declInit Then
  436. PopEnv()
  437. End If
  438. End Method
  439. Method Clear()
  440. End Method
  441. End Type
  442. Type TConstDecl Extends TValDecl
  443. Field value$
  444. Method Create:TConstDecl( ident$,ty:TType,init:TExpr,attrs:Int )
  445. Self.ident=ident
  446. Self.munged=ident
  447. Self.declTy=ty
  448. Self.declInit=init
  449. Self.attrs=attrs
  450. Return Self
  451. End Method
  452. Method GenInstance:TDecl()
  453. Local inst:TConstDecl = New TConstDecl
  454. InitInstance inst
  455. inst.declTy=declTy
  456. inst.declInit=declInit
  457. Return inst
  458. End Method
  459. Method OnCopy:TDecl(deep:Int = True)
  460. If IsSemanted() Then
  461. Return New TConstDecl.Create( ident,ty,CopyInit(), attrs )
  462. Else
  463. Return New TConstDecl.Create( ident, declTy, declInit, attrs)
  464. End If
  465. End Method
  466. Method OnSemant()
  467. Super.OnSemant()
  468. 'If Not IsExtern() value=init.Eval()
  469. If init Then
  470. value=init.Eval()
  471. If TStringType(ty) And Not _appInstance.hasStringConst(value) Then
  472. _appInstance.mapStringConsts(value)
  473. End If
  474. End If
  475. End Method
  476. Method ToString$()
  477. Return "Const "+Super.ToString()
  478. End Method
  479. End Type
  480. Type TVarDecl Extends TValDecl
  481. End Type
  482. Type TLocalDecl Extends TVarDecl
  483. Field done:Int
  484. Field volatile:Int = False
  485. Field declaredInTry:TTryStmtDecl
  486. Method Create:TLocalDecl( ident$,ty:TType,init:TExpr,attrs:Int=0, generated:Int = False, volatile:Int = False )
  487. Self.ident=ident
  488. Self.declTy=ty
  489. Self.declInit=init
  490. Self.attrs=attrs
  491. Self.generated=generated
  492. Self.volatile=volatile
  493. Return Self
  494. End Method
  495. Method OnCopy:TDecl(deep:Int = True)
  496. Local decl:TLocalDecl = New TLocalDecl.Create( ident,declTy,declInit,attrs &~ DECL_SEMANTED, generated, volatile )
  497. decl.scope = scope
  498. decl.ty = ty
  499. decl.init = init
  500. decl.declaredInTry = declaredInTry
  501. Return decl
  502. End Method
  503. Method GetDeclPrefix:String()
  504. Return "Local "
  505. End Method
  506. Method OnSemant()
  507. If declTy Then
  508. If TObjectType(declTy) Or TArrayType(declTy) Then
  509. volatile = True
  510. End If
  511. End If
  512. Super.OnSemant()
  513. End Method
  514. Method ToString$()
  515. Return GetDeclPrefix() + Super.ToString()
  516. End Method
  517. Method Clear()
  518. done = False
  519. End Method
  520. End Type
  521. Type TArgDecl Extends TLocalDecl
  522. Field castTo:String
  523. Method Create:TArgDecl( ident$,ty:TType,init:TExpr,attrs:Int=0, generated:Int = False, volatile:Int = True )
  524. Self.ident=ident
  525. Self.declTy=ty
  526. Self.declInit=init
  527. Self.attrs=attrs
  528. Self.generated=generated
  529. Self.volatile=volatile
  530. Return Self
  531. End Method
  532. Method GenInstance:TDecl()
  533. Local inst:TArgDecl=New TArgDecl
  534. InitInstance inst
  535. inst.declTy=declTy
  536. inst.declInit=declInit
  537. Return inst
  538. End Method
  539. Method OnCopy:TDecl(deep:Int = True)
  540. Local d:TArgDecl = New TArgDecl.Create( ident,declTy,declInit,attrs,generated,volatile )
  541. d.ty = ty
  542. d.init = init
  543. Return d
  544. End Method
  545. Method GetDeclPrefix:String()
  546. Return ""
  547. End Method
  548. Method OnSemant()
  549. Super.OnSemant()
  550. If init And Not TConstExpr(init) Then
  551. If TCastExpr(init) Then
  552. If TConstExpr(TCastExpr(init).expr) Or TNullExpr(TCastExpr(init).expr) Then
  553. Return
  554. End If
  555. End If
  556. If TInvokeExpr(init) And TFunctionPtrType(TInvokeExpr(init).exprType) Then
  557. Return
  558. End If
  559. Err "Function defaults must be constant"
  560. End If
  561. End Method
  562. Method ToString$()
  563. Return Super.ToString()
  564. End Method
  565. End Type
  566. Type TGlobalDecl Extends TVarDecl
  567. Field inited:Int
  568. Field funcGlobal:Int
  569. Method Create:TGlobalDecl( ident$,ty:TType,init:TExpr,attrs:Int=0,funcGlobal:Int=False )
  570. Self.deferInit = True
  571. Self.ident=ident
  572. Self.declTy=ty
  573. Self.declInit=init
  574. Self.attrs=attrs
  575. Self.funcGlobal=funcGlobal
  576. Return Self
  577. End Method
  578. Method OnCopy:TDecl(deep:Int = True)
  579. Local g:TGlobalDecl = New TGlobalDecl.Create( ident,declTy,declInit,attrs,funcGlobal )
  580. g.ty = ty
  581. g.init = init
  582. Return g
  583. End Method
  584. Method ToString$()
  585. Return "Global "+Super.ToString()
  586. End Method
  587. Method GenInstance:TDecl()
  588. ' PushErr errInfo
  589. ' Err "Global variables cannot be used inside generic classes."
  590. Local inst:TGlobalDecl=New TGlobalDecl
  591. InitInstance inst
  592. inst.declTy=declTy
  593. inst.declInit=declInit
  594. Return inst
  595. End Method
  596. Method CheckAccess:Int()
  597. Local cd:TClassDecl = ClassScope()
  598. If cd Then
  599. If cd.modulescope() = _env.modulescope() Return True
  600. If IsPrivate() And cd<>_env.ClassScope() Return False
  601. If IsProtected() Then
  602. Local ec:TClassDecl = _env.ClassScope()
  603. If Not ec Return False
  604. If Not ec.ExtendsClass(cd) Return False
  605. End If
  606. Return True
  607. End If
  608. Return Super.CheckAccess()
  609. End Method
  610. End Type
  611. Type TFieldDecl Extends TVarDecl
  612. ' location offset in object variable data
  613. Field offset:Int
  614. Method Create:TFieldDecl( ident$,ty:TType,init:TExpr,attrs:Int=0 )
  615. Self.ident=ident
  616. Self.declTy=ty
  617. Self.declInit=init
  618. Self.attrs=attrs
  619. Return Self
  620. End Method
  621. Method OnCopy:TDecl(deep:Int = True)
  622. Local f:TFieldDecl = New TFieldDecl.Create( ident,declTy,declInit,attrs )
  623. f.ty = ty
  624. f.init = init
  625. f.metadata = metadata
  626. Return f
  627. End Method
  628. Method ToString$()
  629. Return "Field "+Super.ToString()
  630. End Method
  631. Method GenInstance:TDecl()
  632. Local inst:TFieldDecl=New TFieldDecl
  633. InitInstance inst
  634. inst.declTy=declTy
  635. inst.declInit=declInit
  636. Return inst
  637. End Method
  638. Method CheckAccess:Int()
  639. If ModuleScope() = _env.ModuleScope() Then
  640. Return True
  641. End If
  642. Local cs:TClassDecl = ClassScope()
  643. If IsPrivate() And cs Then
  644. Local ec:TClassDecl = _env.ClassScope()
  645. While ec
  646. If cs = ec Then
  647. Return True
  648. End If
  649. ec = ec.scope.ClassScope()
  650. Wend
  651. If Not ec Then
  652. Return False
  653. End If
  654. End If
  655. If IsProtected() And cs Then
  656. Local ec:TClassDecl = _env.ClassScope()
  657. While ec
  658. If ec.ExtendsClass(cs) Then
  659. Return True
  660. End If
  661. ec = ec.scope.ClassScope()
  662. Wend
  663. If Not ec Then
  664. Return False
  665. End If
  666. End If
  667. Return True
  668. End Method
  669. End Type
  670. Type TAliasDecl Extends TDecl
  671. Field decl:Object
  672. Method Create:TAliasDecl( ident$,decl:Object,attrs:Int=0 )
  673. Self.ident=ident
  674. Self.decl=decl
  675. Self.attrs=attrs
  676. Return Self
  677. End Method
  678. Method OnCopy:TDecl(deep:Int = True)
  679. Return New TAliasDecl.Create( ident,decl,attrs )
  680. End Method
  681. Method OnSemant()
  682. End Method
  683. Method Clear()
  684. End Method
  685. End Type
  686. Type TScopeDecl Extends TDecl
  687. 'Private
  688. Field _decls:TList=New TList'<TDecl>
  689. Field _semanted:TList=New TList'<TDecl>
  690. Field declsMap:TMap=New TMap'<Object>
  691. 'Public
  692. Method OnCopy:TDecl(deep:Int = True)
  693. InternalErr "TScopeDecl.OnCopy"
  694. End Method
  695. Method Decls:TList()
  696. Return _decls
  697. End Method
  698. Method Semanted:TList()
  699. Return _semanted
  700. End Method
  701. Method FuncDecls:TList( id$="" )
  702. Local fdecls:TList=New TList
  703. For Local decl:TDecl=EachIn _decls
  704. If id And decl.ident<>id Continue
  705. Local fdecl:TFuncDecl=TFuncDecl( decl )
  706. If fdecl fdecls.AddLast fdecl
  707. Next
  708. Return fdecls
  709. End Method
  710. Method MethodDecls:TList( id$="" )
  711. Local fdecls:TList=New TList
  712. For Local decl:TDecl=EachIn _decls
  713. If id And decl.ident<>id Continue
  714. Local fdecl:TFuncDecl=TFuncDecl( decl )
  715. If fdecl And fdecl.IsMethod() fdecls.AddLast fdecl
  716. Next
  717. Return fdecls
  718. End Method
  719. Method SemantedFuncs:TList( id$="" )
  720. Local fdecls:TList=New TList
  721. For Local decl:TDecl=EachIn _semanted
  722. If id And decl.ident<>id Continue
  723. Local fdecl:TFuncDecl=TFuncDecl( decl )
  724. If fdecl fdecls.AddLast fdecl
  725. Next
  726. Return fdecls
  727. End Method
  728. Method SemantedMethods:TList( id$="" )
  729. Local fdecls:TList=New TList
  730. For Local decl:TDecl=EachIn _decls
  731. If id And decl.ident<>id Continue
  732. Local fdecl:TFuncDecl=TFuncDecl( decl )
  733. If fdecl And fdecl.IsMethod()
  734. If Not fdecl.IsSemanted() Then
  735. fdecl.Semant()
  736. End If
  737. fdecls.AddLast fdecl
  738. End If
  739. Next
  740. Return fdecls
  741. End Method
  742. Method InsertDecl( decl:TDecl, isCopy:Int = False )
  743. If decl.scope And Not (decl.attrs & DECL_INITONLY) And Not isCopy InternalErr "TScopeDecl.InsertDecl"
  744. 'Local ident$=decl.ident
  745. If Not decl.ident Return
  746. If Not decl.scope Or isCopy Then
  747. decl.scope=Self
  748. End If
  749. _decls.AddLast decl
  750. 'Local _decls:TMap
  751. Local tdecl_:Object=declsMap.ValueForKey( decl.IdentLower() )
  752. If TFuncDecl( decl )
  753. Local funcs:TFuncDeclList=TFuncDeclList( tdecl_ )
  754. If funcs Or Not tdecl_
  755. If Not funcs
  756. funcs=New TFuncDeclList
  757. funcs.ident = decl.IdentLower()
  758. declsMap.Insert decl.IdentLower(),funcs
  759. EndIf
  760. funcs.AddLast TFuncDecl( decl )
  761. Return
  762. Else
  763. Err "Duplicate identifier '"+decl.ident+"'."
  764. EndIf
  765. Else If Not tdecl_
  766. declsMap.Insert decl.IdentLower(),decl
  767. Else
  768. Err "Duplicate identifier '"+decl.ident+"'."
  769. EndIf
  770. End Method
  771. Method InsertDecls( _decls:TList )
  772. For Local decl:TDecl=EachIn _decls
  773. InsertDecl decl
  774. Next
  775. End Method
  776. 'This is overridden by TClassDecl and TModuleDecl
  777. Method GetDecl:Object( ident$ )
  778. 'DebugLog "GetDecl (" + Self.ident + ") : " + ident
  779. Local decl:Object=Object(declsMap.ValueForKey( ident ))
  780. If Not decl Then
  781. If Self.IdentLower() = ident Then
  782. ' name matches but we are a "module", but not a *real* module..
  783. ' .. so we can't be looking for ourself
  784. If TModuleDecl(Self) And Self.ident.Find(".") = - 1 Then
  785. decl = Null
  786. Else
  787. decl = Self
  788. End If
  789. End If
  790. End If
  791. If Not decl Return Null
  792. Local adecl:TAliasDecl=TAliasDecl( decl )
  793. If Not adecl Return decl
  794. If adecl.CheckAccess() Return adecl.decl
  795. End Method
  796. Method FindDecl:Object( ident$, _override:Int = False )
  797. If Not _override And _env<>Self Return GetDecl( ident )
  798. Local tscope:TScopeDecl=Self
  799. While tscope
  800. Local decl:Object=tscope.GetDecl( ident )
  801. If decl Return decl
  802. tscope=tscope.scope
  803. Wend
  804. End Method
  805. Method GetDeclList:Object( ident$, declList:TFuncDeclList = Null, maxSearchDepth:Int )
  806. If Not declList Then
  807. declList = New TFuncDeclList
  808. End If
  809. Local decl:Object=Object(declsMap.ValueForKey( ident ))
  810. If Not decl Return Null
  811. If TFuncDeclList(decl) Then
  812. For Local fdecl:TFuncDecl = EachIn TFuncDeclList(decl)
  813. If Not fdecl.IsSemanted() And Not fdecl.IsSemanting() Then
  814. fdecl.Semant
  815. End If
  816. Local found:Int
  817. ' remove matching functions from decl list.
  818. ' a match should match exactly. If an arg is a subclass of another
  819. ' then that is not a match, and we will distance test later..
  820. For Local func:TFuncDecl = EachIn declList
  821. If func.equalsFunc(fdecl, True) Then
  822. found = True
  823. Exit
  824. 'Else
  825. 'Print func.ToString() + " didn't match " + fdecl.ToString()
  826. End If
  827. Next
  828. If Not found Then
  829. declList.AddLast(fdecl)
  830. End If
  831. Next
  832. Return declList
  833. End If
  834. Return decl
  835. End Method
  836. ' returns a list of all matching named decls in scope
  837. Method FindDeclList:Object(ident:String, _override:Int = False, declList:TFuncDeclList = Null, maxSearchDepth:Int = SCOPE_ALL, skipMultipleClassScopes:Int = False )
  838. If Not declList Then
  839. declList = New TFuncDeclList
  840. End If
  841. If Not _override And _env<>Self Return GetDeclList( ident, declList, maxSearchDepth )
  842. Local hadClassScope:Int
  843. Local tscope:TScopeDecl=Self
  844. While tscope
  845. If TClassDecl(tscope) Then
  846. If skipMultipleClassScopes And hadClassScope Then
  847. tscope=tscope.scope
  848. Continue
  849. End If
  850. hadClassScope = True
  851. End If
  852. Local decl:Object=tscope.GetDeclList( ident, declList, maxSearchDepth )
  853. 'If decl And (Not TFuncDeclList(decl) And declList.IsEmpty()) Return decl
  854. If decl Then
  855. If TFuncDeclList(decl) Then
  856. If TFuncDeclList(decl) <> declList Then
  857. For Local d:TDecl = EachIn TFuncDeclList(decl)
  858. declList.AddLast(d)
  859. Next
  860. End If
  861. Else
  862. declList.AddLast(decl)
  863. End If
  864. End If
  865. ' if scope is an interface, also check implemented/extended interfaces?
  866. If TClassDecl(tscope) Then'And TClassDecl(tscope).IsInterface() Then
  867. If TClassDecl(tscope).implments Then
  868. For Local idecl:TScopeDecl = EachIn TClassDecl(tscope).implments
  869. Local decl:Object=idecl.GetDeclList( ident, declList, maxSearchDepth )
  870. If decl Then
  871. If TFuncDeclList(decl) Then
  872. If TFuncDeclList(decl) <> declList Then
  873. For Local d:TDecl = EachIn TFuncDeclList(decl)
  874. declList.AddLast(d)
  875. Next
  876. End If
  877. Else
  878. declList.AddLast(decl)
  879. End If
  880. End If
  881. Next
  882. End If
  883. End If
  884. tscope=tscope.scope
  885. If TClassDecl(tscope) And maxSearchDepth < SCOPE_CLASS_HEIRARCHY Then
  886. Exit
  887. Else If TModuleDecl(tscope) And maxSearchDepth < SCOPE_ALL Then
  888. Exit
  889. End If
  890. Wend
  891. Return declList
  892. End Method
  893. ' Method FindDecl:Object( ident$, static:Int = False )
  894. ' Local decl:Object=GetDecl( ident )
  895. '
  896. ' If Not static Or Not decl Then
  897. ' If decl Return decl
  898. ' Else
  899. ' If Not TFieldDecl(decl) And Not (TFuncDecl(decl) And TFuncDecl(decl).IsMethod()) Then
  900. ' Return decl
  901. ' End If
  902. ' End If
  903. ' If scope Return scope.FindDecl( ident, static )
  904. ' End Method
  905. Method FindValDecl:TValDecl( ident$, static:Int = False )
  906. Local decl:TValDecl=TValDecl( FindDecl( ident ) )
  907. ' we found a field but we don't have access to it?
  908. If TFieldDecl(decl) And static Then
  909. ' see if there's another decl with the same name elsewhere that we may...
  910. ' field's scope.scope will be a module.
  911. If decl.scope And decl.scope.scope Then
  912. Local vDecl:TValDecl = TValDecl( decl.scope.scope.FindDecl( ident, True ) )
  913. If vDecl Then
  914. decl = vDecl
  915. End If
  916. End If
  917. End If
  918. If Not decl Then
  919. ' try scope search
  920. decl = TValDecl( FindDecl( ident, True ) )
  921. If Not decl Then
  922. ' didn't find it? Maybe it is in module local scope?
  923. ' issue arises when a global initialises with a local variable in the module scope.
  924. Local fdecl:Object = FindDecl("__localmain", True)
  925. If fdecl Then
  926. If TFuncDecl(fdecl) Then
  927. decl = TValDecl( TFuncDecl(fdecl).FindDecl( ident ) )
  928. Else If TFuncDeclList(fdecl) Then
  929. For Local func:TFuncDecl = EachIn TFuncDeclList(fdecl)
  930. func.Semant()
  931. decl = TValDecl( func.FindDecl( ident ) )
  932. If decl Then
  933. Exit
  934. End If
  935. Next
  936. End If
  937. ' a local variable from module local scope can't be seen outside of module local scope...
  938. If TLocalDecl(decl) And static Then
  939. decl = Null
  940. End If
  941. End If
  942. End If
  943. End If
  944. If Not decl Return Null
  945. decl.AssertAccess
  946. decl.Semant
  947. Return decl
  948. End Method
  949. Method FindType:TType( ident$,args:TType[], callback:TCallback = Null )
  950. 'DebugLog Self.ident + "::FindType::" + ident
  951. Local decl:Object=(GetDecl( ident ))
  952. If decl Then
  953. If TModuleDecl(decl) Then
  954. decl = TModuleDecl(decl).GetDecl(ident)
  955. End If
  956. Local ty:TType=TType(decl)
  957. If ty
  958. If args.Length Err "Wrong number of type arguments"
  959. Return ty
  960. EndIf
  961. Local cdecl:TClassDecl=TClassDecl( decl )
  962. If cdecl
  963. cdecl.AssertAccess
  964. If Not cdecl.instanceof Then
  965. cdecl=cdecl.GenClassInstance( args, False, callback, Null )
  966. cdecl.Semant
  967. End If
  968. Return cdecl.objectType
  969. EndIf
  970. Local edecl:TEnumDecl = TEnumDecl(decl)
  971. If edecl Then
  972. Return New TEnumType.Create(edecl)
  973. End If
  974. EndIf
  975. If scope Return scope.FindType( ident,args, callback )
  976. End Method
  977. Method FindScopeDecl:TScopeDecl( ident$ )
  978. Local decl:TScopeDecl=TScopeDecl( FindDecl( ident ) )
  979. If Not decl Return Null
  980. decl.AssertAccess
  981. decl.Semant
  982. Return decl
  983. End Method
  984. Rem
  985. Method FindClassDecl:TClassDecl( ident$,args:TClassDecl[] = Null )
  986. Local decl:TClassDecl=TClassDecl( GetDecl( ident ) )
  987. If Not args Then
  988. args = New TClassDecl[0]
  989. End If
  990. If Not decl
  991. If scope Return scope.FindClassDecl( ident,args )
  992. Return Null
  993. EndIf
  994. decl.AssertAccess
  995. decl.Semant
  996. Return decl.GenClassInstance( args )
  997. End Method
  998. End Rem
  999. Method FindModuleDecl:TModuleDecl( ident$ )
  1000. 'DebugStop
  1001. Local decl:TModuleDecl=TModuleDecl( GetDecl( ident ) )
  1002. If Not decl
  1003. If scope Return scope.FindModuleDecl( ident )
  1004. Return Null
  1005. EndIf
  1006. decl.AssertAccess
  1007. ' only semant on "real" module
  1008. If Not decl.declImported Then
  1009. decl.Semant
  1010. End If
  1011. Return decl
  1012. End Method
  1013. Method FindBestMatchForArgs:TFuncDecl(argExprs:TExpr[], matches:TList)
  1014. Local bestMatch:TFuncDecl = Null
  1015. Local totals:Int[] = New Int[matches.count()]
  1016. Local index:Int
  1017. For Local func:TFuncDecl = EachIn matches
  1018. Local argDecls:TArgDecl[]=func.argDecls
  1019. For Local i:Int=0 Until argDecls.Length
  1020. If i<argExprs.Length And argExprs[i]
  1021. Local declTy:TType=argDecls[i].ty
  1022. Local exprTy:TType=argExprs[i].exprType
  1023. If TFunctionPtrType(declTy) And TInvokeExpr(argExprs[i]) Then
  1024. If TFunctionPtrType(declTy).equalsDecl(TInvokeExpr(argExprs[i]).decl) Then
  1025. Continue
  1026. End If
  1027. End If
  1028. ' not ideal - since the arg is configured as a Byte Ptr, we can't check that the function is of the correct type.
  1029. If IsPointerType(declTy, TType.T_BYTE) And TInvokeExpr(argExprs[i]) And TInvokeExpr(argExprs[i]).invokedWithBraces = 0 Then
  1030. Continue
  1031. End If
  1032. If TFunctionPtrType(declTy) And IsPointerType(exprTy, TType.T_BYTE) Then
  1033. Continue
  1034. End If
  1035. If exprTy.EqualsType( declTy ) Continue
  1036. ' not an exact match. increase distance...
  1037. totals[index] :+ exprTy.DistanceToType(declTy)
  1038. End If
  1039. Next
  1040. index :+ 1
  1041. Next
  1042. Local tot:Int = -1
  1043. index = 0
  1044. Local i:Int
  1045. For Local func:TFuncDecl = EachIn matches
  1046. If tot = -1 Or totals[i] < tot Then
  1047. tot = totals[i]
  1048. bestMatch = func
  1049. Else If tot = totals[i] Then
  1050. If bestMatch.IsMethod() And Not func.IsMethod() Then
  1051. '
  1052. Else If Not bestMatch.IsMethod() And func.IsMethod() Then
  1053. bestMatch = func
  1054. Else If (bestMatch.scope <> func.scope) And (TClassDecl(bestMatch.scope).ExtendsClass(TClassDecl(func.scope))) Then
  1055. ' match is in different level of class hierarchy
  1056. Exit
  1057. Else
  1058. ' a tie?
  1059. Err "Unable to determine overload to use: "+ bestMatch.ToString()+" or "+func.ToString()+"."
  1060. End If
  1061. End If
  1062. i :+ 1
  1063. Next
  1064. Return bestMatch
  1065. End Method
  1066. Method FindFuncDecl:TFuncDecl( ident$,argExprs:TExpr[] = Null,explicit:Int=False, isArg:Int = False, isIdentExpr:Int = False, throwOnNotMatched:Int = False, maxSearchDepth:Int )
  1067. 'DebugLog "FindFuncDecl : " + ident
  1068. 'If ident = "new" Then DebugStop
  1069. Local foundIdentMatch:Int
  1070. Local funcs:TFuncDeclList
  1071. ' does ident exist?
  1072. Local f:Object = FindDeclList(ident, True,,maxSearchDepth)
  1073. If Not f Then Return Null
  1074. funcs = TFuncDeclList( f )
  1075. Local fp:TFuncDecl
  1076. ' not a function list, test for a function ptr var
  1077. If Not funcs Or funcs.IsEmpty() Then
  1078. ' we found a funcdecl
  1079. If TFuncDecl(f) Then
  1080. funcs = New TFuncDeclList
  1081. funcs.AddLast(f)
  1082. End If
  1083. If TVarDecl(f) Then
  1084. If Not TVarDecl(f).IsSemanted() Then
  1085. TVarDecl(f).Semant()
  1086. End If
  1087. If TFunctionPtrType(TVarDecl(f).ty) Then
  1088. funcs = New TFuncDeclList
  1089. fp = TFunctionPtrType(TVarDecl(f).ty).func
  1090. If Not fp.scope Then
  1091. fp.scope = TVarDecl(f).scope
  1092. End If
  1093. If Not fp.ident Then
  1094. fp.ident = TVarDecl(f).ident
  1095. End If
  1096. funcs.AddLast fp
  1097. End If
  1098. End If
  1099. End If
  1100. ' was neither... lets bug out
  1101. If Not funcs Return Null
  1102. ' If Not funcs Then Return Null
  1103. For Local func:TDecl = EachIn funcs
  1104. If Not func.IsSemanting() Then
  1105. func.Semant()
  1106. End If
  1107. Next
  1108. 'Local f:TDecl = TDecl(findDecl(ident))
  1109. 'If Not f Then Return Null
  1110. 'Local func:TFuncDecl = TFuncDecl(f)
  1111. ' If Not func Then
  1112. ' If TVarDecl(f) Then
  1113. ' If Not f.IsSemanted() Then
  1114. ' f.Semant()
  1115. ' End If
  1116. ' If TFunctionPtrType(TVarDecl(f).ty) Then
  1117. ' func = TFunctionPtrType(TVarDecl(f).ty).func
  1118. ' If Not func.scope Then
  1119. ' func.scope = f.scope
  1120. ' End If
  1121. ' If Not func.ident Then
  1122. ' func.ident = f.ident
  1123. ' End If
  1124. ' End If
  1125. ' End If
  1126. ' End If
  1127. ' If Not func Return Null
  1128. If Not argExprs
  1129. argExprs = New TExpr[0]
  1130. End If
  1131. 'func.Semant()
  1132. Local match:TFuncDecl,isexact:Int
  1133. Local _err$
  1134. Local errorDetails:String
  1135. Local matches:TList = New TList
  1136. Local noExtendString:Int = True
  1137. Local generateWarnings:Int = False
  1138. ' double test for matches.
  1139. ' * first time through we don't allow up-casting args to String
  1140. ' if we get a match on the first pass, we'll take it.
  1141. ' * second iteration we allow up-casting numerics to string
  1142. ' * third iteration is valid if opt_warnover is enabled
  1143. ' this will allow down-casting of numerics (eg. double->float)
  1144. ' warnings will be generated if this produces valid results.
  1145. ' if after all that, there's no match, then we can fail it.
  1146. For Local n:Int = 0 Until 3
  1147. If n > 1 Then
  1148. If Not opt_warnover Then
  1149. Continue
  1150. Else
  1151. generateWarnings = True
  1152. End If
  1153. End If
  1154. errorDetails = ""
  1155. If n Then
  1156. noExtendString = False
  1157. End If
  1158. For Local iDecl:TDecl = EachIn funcs
  1159. Local func:TFuncDecl = TFuncDecl(iDecl)
  1160. If Not func Then
  1161. If TVarDecl(iDecl) Then
  1162. ' If Not TVarDecl(iDecl).IsSemanted() Then
  1163. ' TVarDecl(f).Semant()
  1164. ' End If
  1165. If TFunctionPtrType(TVarDecl(iDecl).ty) Then
  1166. 'funcs = New TFuncDeclList
  1167. fp = TFunctionPtrType(TVarDecl(iDecl).ty).func
  1168. If Not fp.scope Then
  1169. fp.scope = TVarDecl(iDecl).scope
  1170. End If
  1171. If Not fp.ident Then
  1172. fp.ident = TVarDecl(iDecl).ident
  1173. End If
  1174. 'funcs.AddLast fp
  1175. func = fp
  1176. End If
  1177. End If
  1178. If Not func Then
  1179. Continue
  1180. End If
  1181. End If
  1182. 'While True
  1183. If Not func.CheckAccess() Continue
  1184. Local argDecls:TArgDecl[]=func.argDecls
  1185. Local exact:Int=True
  1186. Local possible:Int=True
  1187. foundIdentMatch = True
  1188. ' we found a matching name - this is probably the one we mean...
  1189. If isArg Then
  1190. 'match=func
  1191. matches.AddLast(func)
  1192. Exit
  1193. End If
  1194. If argExprs.Length>argDecls.Length
  1195. exact = False
  1196. Continue
  1197. End If
  1198. For Local i:Int=0 Until argDecls.Length
  1199. If i<argExprs.Length And argExprs[i]
  1200. Local arg:TExpr = argExprs[i]
  1201. Local declTy:TType=argDecls[i].ty
  1202. Local exprTy:TType=arg.exprType
  1203. Local widensTest:Int = True
  1204. ' for numeric constants, allow them to be auto-cast unless
  1205. If TConstExpr(arg) And IsNumericType(exprTy) And Not TConstExpr(arg).typeSpecific And TConstExpr(arg).CompatibleWithType(declTy) Then
  1206. widensTest = False
  1207. End If
  1208. If TFunctionPtrType(declTy) And TInvokeExpr(arg) Then
  1209. If TFunctionPtrType(declTy).equalsDecl(TInvokeExpr(arg).decl) Continue
  1210. End If
  1211. ' not ideal - since the arg is configured as a Byte Ptr, we can't check that the function is of the correct type.
  1212. If IsPointerType(declTy, TType.T_BYTE) And TInvokeExpr(arg) And TInvokeExpr(arg).invokedWithBraces = 0 Then
  1213. Continue
  1214. End If
  1215. If TFunctionPtrType(declTy) And IsPointerType(exprTy, TType.T_BYTE) Then
  1216. Continue
  1217. End If
  1218. If exprTy.EqualsType( declTy ) Continue
  1219. exact=False
  1220. If Not generateWarnings Then
  1221. If Not explicit And exprTy.ExtendsType( declTy, noExtendString, widensTest ) Continue
  1222. Else
  1223. If Not explicit Then
  1224. ' fails widen test
  1225. If Not exprTy.ExtendsType( declTy, noExtendString, True ) Then
  1226. ' but passes non-widen test
  1227. If exprTy.ExtendsType( declTy, noExtendString, False ) Then
  1228. ' generate a warning, and accept it
  1229. Warn "In call to " + func.ToString()+ ". Argument #"+(i+1)+" is ~q" + exprTy.ToString()+"~q but declaration is ~q"+declTy.ToString()+"~q. "
  1230. Continue
  1231. End If
  1232. Else
  1233. Continue
  1234. End If
  1235. End If
  1236. End If
  1237. ' make a more helpful error message
  1238. errorDetails :+ "Argument #"+(i+1)+" is ~q" + exprTy.ToString()+"~q but declaration is ~q"+declTy.ToString()+"~q. "
  1239. Else If Not argDecls[i].init
  1240. If (func.attrs & FUNC_PTR) Or isIdentExpr Then
  1241. exact=False
  1242. Exit
  1243. End If
  1244. ' if this argument is missing and there isn't a default...
  1245. errorDetails :+ "Missing function parameter '" + argDecls[i].ident + "'"
  1246. Else ' for case of argdecls having default args
  1247. exact=False
  1248. If Not explicit Exit
  1249. EndIf
  1250. possible=False
  1251. Exit
  1252. Next
  1253. If Not possible Continue
  1254. If exact
  1255. If isexact
  1256. Err "Unable to determine overload to use: "+match.ToString()+" or "+func.ToString()+"."
  1257. Else
  1258. _err=""
  1259. 'match=func
  1260. matches.AddLast(func)
  1261. isexact=True
  1262. Exit
  1263. EndIf
  1264. Else
  1265. If Not isexact
  1266. 'If match
  1267. ' _err="Unable to determine overload to use: "+match.ToString()+" or "+func.ToString()+"."
  1268. 'Else
  1269. 'match=func
  1270. matches.AddLast(func)
  1271. 'EndIf
  1272. EndIf
  1273. EndIf
  1274. 'Exit
  1275. Next
  1276. If Not matches.IsEmpty() Then
  1277. Exit
  1278. End If
  1279. Next
  1280. If matches.Count() = 1 Then
  1281. match = TFuncDecl(matches.First())
  1282. Else
  1283. ' find best match
  1284. match = FindBestMatchForArgs(argExprs, matches)
  1285. End If
  1286. If Not isexact
  1287. If _err Err _err
  1288. If explicit Return Null
  1289. EndIf
  1290. ' last try... maybe we are trying to use it as a function pointer? (no args)
  1291. If Not match Then
  1292. If argExprs Then
  1293. 'match = func
  1294. ' match.maybeFunctionPtr = True
  1295. End If
  1296. Else If Not argExprs Then
  1297. ' 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
  1298. match.maybeFunctionPtr = True
  1299. End If
  1300. If Not match
  1301. Local t$
  1302. For Local i:Int=0 Until argExprs.Length
  1303. If t t:+","
  1304. If argExprs[i] t:+argExprs[i].exprType.ToString()
  1305. Next
  1306. If foundIdentMatch Then
  1307. If throwOnNotMatched Then
  1308. Throw "Unable to find overload for "+ident+"("+t+"). " + errorDetails
  1309. Else
  1310. Err "Unable to find overload for "+ident+"("+t+"). " + errorDetails
  1311. End If
  1312. Else
  1313. If throwOnNotMatched Then
  1314. Throw "Identifier '" + ident + "' not found."
  1315. Else
  1316. Err "Identifier '" + ident + "' not found."
  1317. End If
  1318. End If
  1319. EndIf
  1320. match.AssertAccess
  1321. Return match
  1322. End Method
  1323. Method FindLoop:TStmt(ident:String = Null)
  1324. If TBlockDecl(Self) And TBlockDecl(Self).extra Then
  1325. Local loop:TLoopStmt = TLoopStmt(TBlockDecl(Self).extra)
  1326. If ident Then
  1327. If loop.loopLabel And loop.loopLabel.IdentLower() = ident Then
  1328. Return loop
  1329. End If
  1330. Else
  1331. Return loop
  1332. End If
  1333. End If
  1334. If TFuncDecl(scope) Or TModuleDecl(scope)
  1335. Return Null
  1336. End If
  1337. If scope Return scope.FindLoop( ident )
  1338. End Method
  1339. Method FindTry:TTryStmtDecl()
  1340. If TTryStmtDecl(Self) Then
  1341. Return TTryStmtDecl(Self)
  1342. End If
  1343. If TFuncDecl(scope) Or TModuleDecl(scope)
  1344. Return Null
  1345. End If
  1346. If scope Return scope.FindTry()
  1347. End Method
  1348. Method OnSemant()
  1349. End Method
  1350. Method Clear()
  1351. End Method
  1352. End Type
  1353. Type TBlockDecl Extends TScopeDecl
  1354. Field stmts:TList=New TList
  1355. Field extra:Object
  1356. Field blockType:Int
  1357. Method Create:TBlockDecl( scope:TScopeDecl, generated:Int = False, blockType:Int = BLOCK_OTHER )
  1358. Self.scope = scope
  1359. Self.generated = generated
  1360. Self.blockType = blockType
  1361. attrs :| (scope.attrs & DECL_NODEBUG)
  1362. Return Self
  1363. End Method
  1364. Method AddStmt( stmt:TStmt )
  1365. stmts.AddLast stmt
  1366. End Method
  1367. Method OnCopy:TDecl(deep:Int = True)
  1368. Local t:TBlockDecl=New TBlockDecl
  1369. t.scope = scope
  1370. If deep Then
  1371. For Local stmt:TStmt=EachIn stmts
  1372. t.AddStmt stmt.Copy( t )
  1373. Next
  1374. End If
  1375. t.extra = extra
  1376. t.generated = generated
  1377. t.blockType = blockType
  1378. Return t
  1379. End Method
  1380. Method OnSemant()
  1381. PushEnv Self
  1382. ' any nested functions?
  1383. For Local fdecl:TFuncDecl = EachIn _decls
  1384. fdecl.Semant
  1385. Next
  1386. ' any nested classes?
  1387. For Local cdecl:TClassDecl = EachIn _decls
  1388. cdecl.Semant
  1389. Next
  1390. For Local stmt:TStmt=EachIn stmts
  1391. stmt.Semant
  1392. If TReturnStmt(stmt) Then
  1393. If SurroundingFinallyBlock(Self) Then PushErr stmt.errInfo; Err "Return cannot be used inside a Finally block."
  1394. Else If TBreakStmt(stmt) Then
  1395. Local loop:TLoopStmt
  1396. If TLoopLabelExpr(TBreakStmt(stmt).label) Then
  1397. loop = TLoopLabelExpr(TBreakStmt(stmt).label).loop
  1398. Else
  1399. loop = TLoopStmt(Self.FindLoop())
  1400. End If
  1401. Local f:TBlockDecl = SurroundingFinallyBlock(Self)
  1402. If f And f <> SurroundingFinallyBlock(loop.block) Then PushErr stmt.errInfo; Err "Exit cannot be used to leave a Finally block."
  1403. Else If TContinueStmt(stmt) Then
  1404. Local loop:TLoopStmt
  1405. If TLoopLabelExpr(TContinueStmt(stmt).label) Then
  1406. loop = TLoopLabelExpr(TContinueStmt(stmt).label).loop
  1407. Else
  1408. loop = TLoopStmt(Self.FindLoop())
  1409. End If
  1410. Local f:TBlockDecl = SurroundingFinallyBlock(Self)
  1411. If f And f <> SurroundingFinallyBlock(loop.block) Then PushErr stmt.errInfo; Err "Continue cannot be used to leave a Finally block."
  1412. End If
  1413. Function SurroundingFinallyBlock:TBlockDecl(block:TBlockDecl)
  1414. ' get the innermost Finally block surrounding the current statement
  1415. While block And Not TFuncDecl(block)
  1416. If block.blockType = BLOCK_FINALLY Then Return block
  1417. block = TBlockDecl(block.scope)
  1418. Wend
  1419. Return Null
  1420. End Function
  1421. Next
  1422. PopEnv
  1423. End Method
  1424. Method CopyBlock:TBlockDecl( scope:TScopeDecl )
  1425. Local t:TBlockDecl=TBlockDecl( Copy() )
  1426. t.scope=scope
  1427. Return t
  1428. End Method
  1429. Method Clear()
  1430. For Local stmt:TStmt=EachIn stmts
  1431. stmt.Clear
  1432. Next
  1433. End Method
  1434. Method ToString:String()
  1435. Select blockType
  1436. Case BLOCK_FUNCTION
  1437. Return Super.ToString()
  1438. Case BLOCK_OTHER
  1439. Return "TBlockDecl:Other"
  1440. Case BLOCK_LOOP
  1441. Return "TBlockDecl:Loop"
  1442. Case BLOCK_TRY
  1443. Return "TBlockDecl:Try"
  1444. Case BLOCK_CATCH
  1445. Return "TBlockDecl:Catch"
  1446. Case BLOCK_FINALLY
  1447. Return "TBlockDecl:Finally"
  1448. Case BLOCK_IF
  1449. Return "TBlockDecl:If"
  1450. Case BLOCK_ELSE
  1451. Return "TBlockDecl:Else"
  1452. Default
  1453. Return "TBlockDecl:Unknown"
  1454. End Select
  1455. End Method
  1456. End Type
  1457. Const FUNC_METHOD:Int= $0001 'mutually exclusive with ctor
  1458. Const FUNC_CTOR:Int= $0002
  1459. Const FUNC_PROPERTY:Int= $0004
  1460. Const FUNC_DTOR:Int= $0008
  1461. Const FUNC_BUILTIN:Int = $0080
  1462. Const FUNC_PTR:Int= $0100
  1463. Const FUNC_INIT:Int = $0200
  1464. Const FUNC_NESTED:Int = $0400
  1465. Const FUNC_OPERATOR:Int= $0800
  1466. Const FUNC_FIELD:Int= $1000
  1467. 'Fix! A func is NOT a block/scope!
  1468. '
  1469. Type TFuncDecl Extends TBlockDecl
  1470. Field retType:TType
  1471. Field retTypeExpr:TType
  1472. Field argDecls:TArgDecl[]
  1473. Field overrides:TFuncDecl
  1474. Field superCtor:TInvokeSuperExpr
  1475. Field castTo:String
  1476. Field noCastGen:Int
  1477. Field maybeFunctionPtr:Int
  1478. Field returnTypeSubclassed:Int
  1479. Field mangled:String
  1480. Field noMangle:Int
  1481. Field exported:Int
  1482. Field equalsBuiltIn:Int = -1
  1483. Method CreateF:TFuncDecl( ident$,ty:TType,argDecls:TArgDecl[],attrs:Int )
  1484. Self.ident=ident
  1485. Self.retTypeExpr=ty
  1486. If argDecls
  1487. Self.argDecls=argDecls
  1488. Else
  1489. Self.argDecls = New TArgDecl[0]
  1490. End If
  1491. Self.attrs=attrs
  1492. Self.blockType = BLOCK_FUNCTION
  1493. Return Self
  1494. End Method
  1495. Method OnCopy:TDecl(deep:Int = True)
  1496. Local args:TArgDecl[]=argDecls[..]
  1497. For Local i:Int=0 Until args.Length
  1498. args[i]=TArgDecl( args[i].Copy() )
  1499. Next
  1500. Local t:TFuncDecl=New TFuncDecl.CreateF( ident,retType,args,attrs)
  1501. If deep Then
  1502. For Local stmt:TStmt=EachIn stmts
  1503. t.AddStmt stmt.Copy( t )
  1504. Next
  1505. End If
  1506. t.retType = retType
  1507. t.retTypeExpr = retTypeExpr
  1508. t.scope = scope
  1509. t.overrides = overrides
  1510. t.superCtor = superCtor
  1511. t.castTo = castTo
  1512. t.noCastGen = noCastGen
  1513. t.munged = munged
  1514. t.metadata = metadata
  1515. t.mangled = mangled
  1516. t.noMangle = noMangle
  1517. t.exported = exported
  1518. t.blockType = blockType
  1519. Return t
  1520. End Method
  1521. Method GenInstance:TDecl()
  1522. Local inst:TFuncDecl=New TFuncDecl
  1523. InitInstance inst
  1524. inst.retTypeExpr=retTypeExpr
  1525. inst.argDecls=argDecls[..]
  1526. For Local i:Int=0 Until argDecls.Length
  1527. inst.argDecls[i]=TArgDecl( argDecls[i].GenInstance() )
  1528. Next
  1529. Return inst
  1530. End Method
  1531. Method ToString$()
  1532. Local t$
  1533. For Local decl:TArgDecl=EachIn argDecls
  1534. If t t:+","
  1535. t:+decl.ToString()
  1536. Next
  1537. Local q$
  1538. If IsCtor()
  1539. q="Method "+Super.ToString()
  1540. Else
  1541. If IsMethod() q="Method " Else q="Function "
  1542. q:+Super.ToString()
  1543. If retType
  1544. If Not TVoidType(retType) Then
  1545. q:+":"+retType.ToString()
  1546. End If
  1547. Else If retTypeExpr
  1548. q:+":"+retTypeExpr.ToString()
  1549. 'Else
  1550. ' q:+":"+"?"
  1551. EndIf
  1552. EndIf
  1553. Return q+"("+t+")"
  1554. End Method
  1555. Method ToTypeString:String()
  1556. Local t$
  1557. For Local decl:TArgDecl=EachIn argDecls
  1558. If t t:+","
  1559. t:+decl.ToTypeString()
  1560. Next
  1561. Local q$
  1562. If Not IsCtor() Then
  1563. If retType
  1564. If Not TVoidType(retType) Then
  1565. q:+retType.ToString()
  1566. End If
  1567. Else If retTypeExpr
  1568. q:+retTypeExpr.ToString()
  1569. EndIf
  1570. End If
  1571. Return q+"("+t+")"
  1572. End Method
  1573. Method IsBuiltIn:Int()
  1574. Return (attrs & FUNC_BUILTIN)<>0
  1575. End Method
  1576. Method IsCtor:Int()
  1577. Return (attrs & FUNC_CTOR)<>0
  1578. End Method
  1579. Method IsDtor:Int()
  1580. Return (attrs & FUNC_DTOR)<>0
  1581. End Method
  1582. Method IsMethod:Int()
  1583. Return (attrs & FUNC_METHOD)<>0
  1584. End Method
  1585. Method IsAnyMethod:Int()
  1586. Return IsMethod() Or IsCtor() Or IsDtor()
  1587. End Method
  1588. Method IsStatic:Int()
  1589. Return (attrs & (FUNC_METHOD|FUNC_CTOR))=0
  1590. End Method
  1591. Method IsProperty:Int()
  1592. Return (attrs & FUNC_PROPERTY)<>0
  1593. End Method
  1594. Method IsField:Int()
  1595. Return (attrs & FUNC_FIELD)<>0
  1596. End Method
  1597. ' exactMatch requires args to be equal. If an arg is a subclass, that is not a match.
  1598. Method EqualsArgs:Int( decl:TFuncDecl, exactMatch:Int = False ) ' careful, this is not commutative!
  1599. If argDecls.Length<>decl.argDecls.Length Return False
  1600. For Local i:Int=0 Until argDecls.Length
  1601. ' ensure arg decls have been semanted
  1602. decl.argDecls[i].Semant()
  1603. argDecls[i].Semant()
  1604. ' objects can be subclasses as well as the same.
  1605. If TObjectType(decl.argDecls[i].ty) Then
  1606. If Not decl.argDecls[i].ty.EqualsType( argDecls[i].ty ) And (exactMatch Or Not decl.argDecls[i].ty.ExtendsType( argDecls[i].ty )) Return False
  1607. Else
  1608. If Not decl.argDecls[i].ty.EqualsType( argDecls[i].ty ) Return False
  1609. End If
  1610. Next
  1611. Return True
  1612. End Method
  1613. ' exactMatch requires args to be equal. If an arg is a subclass, that is not a match.
  1614. Method EqualsFunc:Int( decl:TFuncDecl, exactMatch:Int = False) ' careful, this is not commutative!
  1615. If IsCtor() Then
  1616. Return EqualsArgs( decl, exactMatch )
  1617. Else
  1618. ' matching args?
  1619. If EqualsArgs( decl, exactMatch ) Then
  1620. ' matching return type?
  1621. If TObjectType(retType) Or TArrayType(retType) Or TStringType(retType) Then
  1622. Return retType.EqualsType( decl.retType ) Or retType.ExtendsType( decl.retType )' Or decl.retType.EqualsType( retType )) And EqualsArgs( decl )
  1623. Else
  1624. Return retType.EqualsType( decl.retType )
  1625. End If
  1626. End If
  1627. End If
  1628. Return False
  1629. End Method
  1630. Method OnSemant()
  1631. Local strictVoidToInt:Int = False
  1632. If isCtor() Or isDtor() Then
  1633. If retTypeExpr And Not TVoidType(retTypeExpr) Then
  1634. Err ident + "() cannot specify a return type"
  1635. End If
  1636. If ClassScope() And ClassScope().IsInterface() Then
  1637. Err ident + "() cannot be declared in an Interface."
  1638. End If
  1639. If IsCtor() retTypeExpr=New TObjectType.Create( TNewDecl(Self).cDecl )
  1640. End If
  1641. 'semant ret type
  1642. If Not retTypeExpr Then
  1643. If Not retType Then ' may have previously been set (if this is a function pointer)
  1644. retType = TType.voidType
  1645. Else If TIdentType(retType)
  1646. retType = retType.Semant()
  1647. Else
  1648. ' for Strict code, a void return type becomes Int
  1649. If TVoidType(retType) And Not ModuleScope().IsSuperStrict() Then
  1650. strictVoidToInt = True
  1651. retType = New TIntType
  1652. End If
  1653. End If
  1654. Else
  1655. ' pass the scope into the function ptr
  1656. Local retTypeExpr_:TType = retTypeExpr
  1657. While TArrayType(retTypeExpr_) ' look into array types, since the element type might be function ptr
  1658. retTypeExpr_ = TArrayType(retTypeExpr_).elemType
  1659. Wend
  1660. If TFunctionPtrType(retTypeExpr_) Then
  1661. If Not TFunctionPtrType(retTypeExpr_).func.scope Then
  1662. If scope Then
  1663. TFunctionPtrType(retTypeExpr_).func.scope = scope
  1664. Else
  1665. TFunctionPtrType(retTypeExpr_).func.scope = _env
  1666. End If
  1667. End If
  1668. End If
  1669. retType=retTypeExpr.Semant()
  1670. ' for Strict code, a void return type becomes Int
  1671. If TVoidType(retType) And Not ModuleScope().IsSuperStrict() And Not IsDTor() Then
  1672. strictVoidToInt = True
  1673. retType = New TIntType
  1674. End If
  1675. End If
  1676. If TArrayType( retType ) And Not retType.EqualsType( retType.ActualType() )
  1677. ' Err "Return type cannot be an array of generic objects."
  1678. EndIf
  1679. 'semant args
  1680. For Local arg:TArgDecl=EachIn argDecls
  1681. InsertDecl arg
  1682. arg.Semant
  1683. Next
  1684. ' if we are a function pointer declaration, we just want to semant the args here.
  1685. If attrs & FUNC_PTR Return
  1686. If actual<>Self Return
  1687. 'check for duplicate decl
  1688. If ident Then
  1689. For Local decl:TFuncDecl=EachIn scope.SemantedFuncs( ident )
  1690. If decl<>Self And EqualsArgs( decl, True ) And Not decl.IsCTOR()
  1691. Err "Duplicate declaration "+ToString()
  1692. EndIf
  1693. If noMangle Then
  1694. If decl<>Self Then
  1695. If decl.argDecls.Length = 0 Then
  1696. Err "You cannot apply NoMangle to the function, as another function with no arguments exists."
  1697. Else If decl.NoMangle Then
  1698. Err "Another function is already declared with NoMangle."
  1699. End If
  1700. End If
  1701. End If
  1702. If exported Then
  1703. If decl<>Self Then
  1704. If decl.argDecls.Length = 0 Then
  1705. Err "You cannot apply Export to the function, as another function with no arguments exists."
  1706. Else If decl.exported Then
  1707. Err "Another function is already declared with Export."
  1708. End If
  1709. End If
  1710. End If
  1711. Next
  1712. End If
  1713. ' any nested functions?
  1714. For Local fdecl:TFuncDecl = EachIn _decls
  1715. fdecl.Semant
  1716. Next
  1717. 'get cdecl, sclasss
  1718. Local cdecl:TClassDecl=ClassScope(),sclass:TClassDecl
  1719. If cdecl sclass=TClassDecl( cdecl.superClass )
  1720. 'prefix call to super ctor if necessary
  1721. ' If IsCtor() And superCtor=Null And sclass
  1722. ' If sclass.FindFuncDecl( "new", Null )
  1723. ' superCtor=New TInvokeSuperExpr.Create( "new" )
  1724. ' stmts.AddFirst New TExprStmt.Create( superCtor )
  1725. ' EndIf
  1726. ' EndIf
  1727. 'check we exactly match an override
  1728. If sclass 'And IsMethod()
  1729. Local found:Int
  1730. While sclass
  1731. Local errorDetails:String = ""
  1732. found = MatchesFunction(sclass, strictVoidToInt, errorDetails)
  1733. ' check interfaces?
  1734. If Not found Then
  1735. If sclass = cdecl.superClass Then
  1736. found = MatchesInterfaceFunction(cdecl, strictVoidToInt, errorDetails)
  1737. End If
  1738. If Not found Then
  1739. found = MatchesInterfaceFunction(sclass, strictVoidToInt, errorDetails)
  1740. End If
  1741. End If
  1742. If found
  1743. If Not overrides Err "Overriding method does not match any overridden method. (Detail: " + errorDetails+")"
  1744. If overrides.IsFinal() Err "Final methods cannot be overridden."
  1745. If Not (attrs & DECL_OVERRIDE) And opt_require_override And Not declImported Then
  1746. Local msg:String = "Overriding method '" + ident + "' must be declared with 'Override'."
  1747. If Not opt_override_error Then
  1748. Warn msg
  1749. Else
  1750. Err msg
  1751. End If
  1752. End If
  1753. ' for overrides, make the ident match that of the superclass
  1754. ident = overrides.ident
  1755. Exit
  1756. EndIf
  1757. sclass=sclass.superClass
  1758. Wend
  1759. If Not found And attrs & DECL_OVERRIDE Then
  1760. Err "Method does not override method from its super type."
  1761. End If
  1762. EndIf
  1763. 'append a return statement if necessary
  1764. If Not IsExtern() And Not TVoidType( retType ) And Not TReturnStmt( stmts.Last() )
  1765. If Not isCtor() And Not isDtor()
  1766. Local stmt:TReturnStmt
  1767. stmt=New TReturnStmt.Create( New TConstExpr.Create( retType,"" ) )
  1768. stmt.generated = True
  1769. stmt.errInfo=errInfo
  1770. stmts.AddLast stmt
  1771. End If
  1772. EndIf
  1773. attrs:|DECL_SEMANTED
  1774. Super.OnSemant()
  1775. End Method
  1776. Method MatchesInterfaceFunction:Int(cdecl:TClassDecl, strictVoidToInt:Int, errorDetails:String Var)
  1777. Local found:Int
  1778. If Not found Then
  1779. For Local idecl:TClassDecl = EachIn cdecl.implments
  1780. found = MatchesFunction(idecl, strictVoidToInt, errorDetails)
  1781. If Not found Then
  1782. found = MatchesInterfaceFunction(idecl, strictVoidToInt, errorDetails)
  1783. End If
  1784. If found Then
  1785. Exit
  1786. End If
  1787. Next
  1788. End If
  1789. Return found
  1790. End Method
  1791. Method MatchesFunction:Int(sclass:TClassDecl, strictVoidToInt:Int, errorDetails:String Var)
  1792. Local found:Int
  1793. For Local decl:TFuncDecl=EachIn sclass.FuncDecls( )
  1794. If decl.IdentLower() = IdentLower() Then
  1795. If IdentLower() = "new" Continue
  1796. If IdentLower() = "delete" Continue
  1797. found=True
  1798. If Not decl.IsSemanted() Then
  1799. decl.Semant
  1800. End If
  1801. ' check void return type strictness, and fail if appropriate.
  1802. Local voidReturnTypeFail:Int = False
  1803. ' super has void return type... so it is superstrict (or inherited from)
  1804. If TVoidType(decl.retType) And TIntType(retType) Then
  1805. ' if we are only strict, we may fail on type mismatch
  1806. If Not ModuleScope().IsSuperStrict() Then
  1807. ' we have the option of upgrading our return type to match superstrict parent
  1808. If opt_strictupgrade And strictVoidToInt Then
  1809. retType = TType.voidType
  1810. Else
  1811. ' otherwise...
  1812. voidReturnTypeFail = True
  1813. End If
  1814. End If
  1815. End If
  1816. If EqualsFunc( decl ) And Not voidReturnTypeFail
  1817. ' check we aren't attempting to assign weaker access modifiers
  1818. If (IsProtected() And decl.IsPublic()) Or (IsPrivate() And (decl.IsProtected() Or decl.IsPublic())) Then
  1819. Err PrivilegeError(Self, decl)
  1820. End If
  1821. If (TObjectType(retType) And TObjectType(decl.retType )) Or (TArrayType(retType) And TArrayType(decl.retType)) Then
  1822. If Not retType.EqualsType( decl.retType ) And retType.ExtendsType( decl.retType ) Then
  1823. returnTypeSubclassed = True
  1824. End If
  1825. End If
  1826. overrides=TFuncDecl( decl.actual )
  1827. Else
  1828. ' method overloading?
  1829. If Not EqualsArgs(decl) Then
  1830. found = False
  1831. Continue
  1832. End If
  1833. 'prepare a more detailed error message
  1834. If (Not retType.EqualsType( decl.retType ) Or Not retType.ExtendsType( decl.retType )) Or (decl.retType And Not decl.retType.EqualsType( retType )) Or voidReturnTypeFail
  1835. errorDetails :+ "Return type is ~q"+retType.ToString()+"~q, expected ~q"+decl.retType.ToString()+"~q. "
  1836. If voidReturnTypeFail Then
  1837. errorDetails :+ "You may have Strict type overriding SuperStrict type. "
  1838. End If
  1839. Else
  1840. found = False
  1841. Continue
  1842. End If
  1843. Local argCount:Int = Min(argDecls.Length, decl.argDecls.Length)
  1844. If argCount > 0
  1845. For Local i:Int=0 Until argCount
  1846. If Not argDecls[i].ty.EqualsType( decl.argDecls[i].ty )
  1847. errorDetails :+ "Argument #"+(i+1)+" is ~q" + argDecls[i].ty.ToString()+"~q, expected ~q"+decl.argDecls[i].ty.ToString()+"~q. "
  1848. End If
  1849. Next
  1850. EndIf
  1851. 'remove last space
  1852. errorDetails = errorDetails.Trim()
  1853. EndIf
  1854. End If
  1855. If found Exit
  1856. Next
  1857. Return found
  1858. End Method
  1859. Method CheckAccess:Int()
  1860. If ModuleScope() = _env.ModuleScope() Return True
  1861. Local cd:TClassDecl = ClassScope()
  1862. If cd Then
  1863. If IsPrivate() And cd<>_env.ClassScope() Return False
  1864. If IsProtected() Then
  1865. Local ec:TClassDecl = _env.ClassScope()
  1866. If Not ec Return False
  1867. If Not ec.ExtendsClass(cd) Return False
  1868. End If
  1869. Return True
  1870. End If
  1871. Return Super.CheckAccess()
  1872. End Method
  1873. Function PrivilegeError:String(decl:TFuncDecl, decl2:TFuncDecl)
  1874. Local p:String
  1875. If decl.IsProtected() Then
  1876. p = "Protected"
  1877. Else
  1878. p = "Private"
  1879. End If
  1880. Local dp:String
  1881. If decl2.IsPublic() Then
  1882. dp = "Public"
  1883. Else
  1884. dp = "Protected"
  1885. End If
  1886. Return decl.ToString() + " clashes with " + decl2.ToString() + ". Attempt to assign weaker access privileges ('" + p + "'), was '" + dp + "'."
  1887. End Function
  1888. End Type
  1889. Type TNewDecl Extends TFuncDecl
  1890. Field chainedCtor:TNewExpr
  1891. Field cdecl:TClassDecl
  1892. Method OnCopy:TDecl(deep:Int = True)
  1893. Local args:TArgDecl[]=argDecls[..]
  1894. For Local i:Int=0 Until args.Length
  1895. args[i]=TArgDecl( args[i].Copy() )
  1896. Next
  1897. Local t:TNewDecl = TNewDecl(New TNewDecl.CreateF( ident,retType,args,attrs &~DECL_SEMANTED ))
  1898. If deep Then
  1899. For Local stmt:TStmt=EachIn stmts
  1900. t.AddStmt stmt.Copy(t)
  1901. Next
  1902. End If
  1903. t.retType = retType
  1904. t.scope = scope
  1905. t.overrides = overrides
  1906. t.superCtor = superCtor
  1907. t.castTo = castTo
  1908. t.noCastGen = noCastGen
  1909. t.munged = munged
  1910. t.metadata = metadata
  1911. t.mangled = mangled
  1912. t.noMangle = noMangle
  1913. t.chainedCtor = chainedCtor
  1914. Return t
  1915. End Method
  1916. End Type
  1917. 'Const CLASS_INTERFACE:Int=1
  1918. 'Const CLASS_TEMPLATEARG:Int=2
  1919. 'Const CLASS_TEMPLATEINST:Int=4
  1920. 'Const CLASS_INSTANCED:Int=8 'class used in New?
  1921. Const CLASS_INSTANCED:Int=1
  1922. Const CLASS_EXTENDSOBJECT:Int=2
  1923. Const CLASS_FINALIZED:Int=4
  1924. Type TNullDecl Extends TClassDecl
  1925. End Type
  1926. ' used to handle recursive generics
  1927. ' by setting the superclass as soon as we know it,
  1928. ' which allows the semanting of the instance to complete.
  1929. Type TClassDeclCallback Extends TCallback
  1930. Field decl:TClassDecl
  1931. Method callback(obj:Object)
  1932. decl.superClass = TClassDecl(obj)
  1933. End Method
  1934. End Type
  1935. Type TClassDecl Extends TScopeDecl
  1936. Field lastOffset:Int
  1937. Field args:TTemplateArg[]
  1938. Field superTy:TIdentType
  1939. Field impltys:TIdentType[]
  1940. Field superClass:TClassDecl
  1941. Field implments:TClassDecl[] 'interfaces immediately implemented
  1942. Field implmentsAll:TClassDecl[] 'all interfaces implemented
  1943. Field instanceof:TClassDecl 'for instances
  1944. Field instances:TList 'for actual (non-arg, non-instance)
  1945. Field instArgs:TType[]
  1946. Field objectType:TObjectType '"canned" objectType
  1947. Field globInit:Int
  1948. Field templateSource:TTemplateRecord
  1949. 'Global nullObjectClass:TClassDecl=New TNullDecl.Create( "{NULL}",Null,Null,Null,DECL_ABSTRACT|DECL_EXTERN )
  1950. Method Create:TClassDecl( ident$,args:TTemplateArg[],superTy:TIdentType,impls:TIdentType[],attrs:Int )
  1951. Self.ident=ident
  1952. Self.args=args
  1953. Self.superTy=superTy
  1954. Self.impltys=impls
  1955. Self.attrs=attrs
  1956. Self.objectType=New TObjectType.Create( Self )
  1957. If args
  1958. instances=New TList
  1959. EndIf
  1960. Return Self
  1961. End Method
  1962. Method OnCopy:TDecl(deep:Int = True)
  1963. InternalErr "TClassDecl.OnCopy"
  1964. End Method
  1965. Method ToString$()
  1966. Local t$
  1967. If args Then
  1968. For Local i:Int=0 Until args.Length
  1969. If i Then
  1970. t :+ ","
  1971. End If
  1972. t:+args[i].ToString()
  1973. Next
  1974. ElseIf instargs
  1975. For Local i:Int=0 Until instargs.Length
  1976. If i Then
  1977. t :+ ","
  1978. End If
  1979. t :+ instargs[i].ToString()
  1980. Next
  1981. End If
  1982. If t t="<"+t+">"
  1983. Return ident+t
  1984. End Method
  1985. Method ToTypeString:String()
  1986. Return ToString()
  1987. End Method
  1988. Rem
  1989. Method GenClassInstance:TClassDecl( instArgs:TClassDecl[] )
  1990. If Not IsSemanted() InternalErr
  1991. 'no args
  1992. If Not instArgs
  1993. If Not args Return Self
  1994. If instanceof Return Self
  1995. For Local inst:TClassDecl=EachIn instances
  1996. If _env.ClassScope()=inst Return inst
  1997. Next
  1998. EndIf
  1999. 'If Not instanceof And Not instArgs Return Self
  2000. 'check number of args
  2001. If instanceof Or args.Length<>instArgs.Length
  2002. Err "Wrong number of class arguments for "+ToString()
  2003. EndIf
  2004. 'look for existing instance
  2005. For Local inst:TClassDecl=EachIn instances
  2006. Local equal:Int=True
  2007. For Local i:Int=0 Until args.Length
  2008. If inst.args[i]=instArgs[i] Continue
  2009. equal=False
  2010. Exit
  2011. Next
  2012. If equal Return inst
  2013. Next
  2014. Local inst:TClassDecl=New TClassDecl
  2015. InitInstance inst
  2016. inst.scope=scope
  2017. inst.attrs:|CLASS_TEMPLATEINST
  2018. inst.args=instArgs
  2019. inst.superTy=superTy
  2020. inst.instanceof=Self
  2021. instances.AddLast inst
  2022. For Local i:Int=0 Until args.Length
  2023. inst.InsertDecl New TAliasDecl.Create( args[i].ident,instArgs[i] )
  2024. Next
  2025. For Local decl:TDecl=EachIn _decls
  2026. If TClassDecl( decl ) Continue
  2027. inst.InsertDecl decl.GenInstance()
  2028. Next
  2029. 'inst.Semant
  2030. 'A bit cheeky...
  2031. inst.OnSemant
  2032. inst.attrs:|DECL_SEMANTED
  2033. Return inst
  2034. End Method
  2035. End Rem
  2036. Method GenClassInstance:TClassDecl( instArgs:TType[], declImported:Int = False, callback:TCallback = Null, templateDets:TTemplateDets = Null )
  2037. If instanceof InternalErr "TClassDecl.GenClassInstance"
  2038. 'no args
  2039. If Not instArgs
  2040. If Not args Return Self
  2041. For Local inst:TClassDecl=EachIn instances
  2042. If _env.ClassScope()=inst Return inst
  2043. Next
  2044. EndIf
  2045. Local originalInstArgs:TType[] = instArgs
  2046. 'check number of args
  2047. If args.Length<>instArgs.Length Then
  2048. If Not templateDets Or args.Length > instArgs.Length Then
  2049. Err "Wrong number of type arguments for class "+ToString()
  2050. Else
  2051. ' create new instArgs with matched aliases
  2052. Local newInstArgs:TType[] = New TType[args.length]
  2053. For Local i:Int = 0 Until args.length
  2054. Local arg:TTemplateArg = args[i]
  2055. Local instArg:TType
  2056. ' find match
  2057. For Local n:Int = 0 Until templateDets.args.length
  2058. Local templateArg:TTemplateArg = templateDets.args[n]
  2059. If templateArg.ident.ToLower() = arg.ident.ToLower() Then
  2060. instArg = instArgs[n]
  2061. Exit
  2062. End If
  2063. Next
  2064. If Not instArg Then
  2065. Err "Cannot find argument type '" + arg.ident + "' for class " + ToString()
  2066. End If
  2067. newInstArgs[i] = instArg
  2068. Next
  2069. instArgs = newInstArgs
  2070. End If
  2071. EndIf
  2072. 'look for existing instance
  2073. For Local inst:TClassDecl=EachIn instances
  2074. Local equal:Int=True
  2075. For Local i:Int=0 Until args.Length
  2076. If Not inst.instArgs[i].EqualsType( instArgs[i] )
  2077. equal=False
  2078. Exit
  2079. EndIf
  2080. Next
  2081. If equal Return inst
  2082. Next
  2083. If Not templateDets Then
  2084. ' pass in the original instargs, as an inner-inner type will be able to see all of the originals
  2085. templateDets = New TTemplateDets.Create(originalInstArgs, args)
  2086. End If
  2087. Local inst:TClassDecl = TClassDecl(TGenProcessor.processor.ParseGeneric(templateSource, templateDets))
  2088. inst.ident=ident
  2089. inst.args=Null
  2090. inst.instances = Null
  2091. inst.superTy=superTy
  2092. inst.impltys=impltys
  2093. inst.attrs=attrs
  2094. inst.attrs:&~DECL_SEMANTED
  2095. inst.munged=munged
  2096. inst.errInfo=errInfo
  2097. inst.scope=scope
  2098. inst.instanceof=Self
  2099. inst.instArgs=instArgs
  2100. inst.templateSource = templateSource
  2101. instances.AddLast inst
  2102. inst.declImported = declImported
  2103. If callback Then
  2104. callback.callback(inst)
  2105. End If
  2106. PushEnv inst
  2107. ' install aliases
  2108. For Local i:Int=0 Until args.Length
  2109. inst.InsertDecl New TAliasDecl.Create( args[i].ident,instArgs[i],0 )
  2110. Next
  2111. ' process parameter types
  2112. For Local i:Int=0 Until args.Length
  2113. Local arg:TTemplateArg = args[i]
  2114. ' ensure parameter types are compatible
  2115. If arg.superTy Then
  2116. 'If Not instArgs[i].IsSemanted() Then
  2117. If TObjectType(instArgs[i]) Then
  2118. TObjectType(instArgs[i]).classDecl.Semant()
  2119. End If
  2120. 'End If
  2121. For Local n:Int = 0 Until arg.superTy.length
  2122. arg.superTy[n] = arg.superTy[n].Semant()
  2123. If Not instArgs[i].EqualsType(arg.superTy[n]) And Not instArgs[i].ExtendsType(arg.superTy[n]) Then
  2124. Err "Type parameter '" + instArgs[i].ToString() + "' is not within its bound; should extend '" + arg.superTy[n].ToString() + "'"
  2125. End If
  2126. Next
  2127. End If
  2128. Next
  2129. PopEnv
  2130. ' For Local decl:TDecl=EachIn _decls
  2131. ' If TClassDecl(decl) Then
  2132. ' inst.InsertDecl TClassDecl(decl).GenClassInstance(instArgs, declImported), True
  2133. ' Else
  2134. ' inst.InsertDecl decl.Copy(), True
  2135. ' End If
  2136. ' Next
  2137. If Not declImported Then
  2138. inst.scope = _env.ModuleScope()
  2139. End If
  2140. Return inst
  2141. End Method
  2142. Method IsInterface:Int()
  2143. Return (attrs & CLASS_INTERFACE)<>0
  2144. End Method
  2145. Method IsThrowable:Int()
  2146. Return (attrs & CLASS_THROWABLE)<>0
  2147. End Method
  2148. Method IsFinalized:Int()
  2149. Return (attrs & CLASS_FINALIZED)<>0
  2150. End Method
  2151. Method IsStruct:Int()
  2152. Return (attrs & CLASS_STRUCT)<>0
  2153. End Method
  2154. Method ExtendsObject:Int()
  2155. Return (attrs & CLASS_EXTENDSOBJECT)<>0
  2156. End Method
  2157. Method IsInstanced:Int()
  2158. Return (attrs & CLASS_INSTANCED)<>0
  2159. End Method
  2160. Method GetDecl:Object( ident$ )
  2161. Local cdecl:TClassDecl=Self
  2162. While cdecl
  2163. Local decl:Object=cdecl.GetDecl2( ident )
  2164. If decl Return decl
  2165. cdecl=cdecl.superClass
  2166. Wend
  2167. End Method
  2168. 'needs this 'coz you can't go blah.Super.GetDecl()...
  2169. Method GetDecl2:Object( ident$ )
  2170. Return Super.GetDecl( ident )
  2171. End Method
  2172. Method GetDeclList:Object( ident$, declList:TFuncDeclList = Null, maxSearchDepth:Int )
  2173. If Not declList Then
  2174. declList = New TFuncDeclList
  2175. End If
  2176. Local cdecl:TClassDecl=Self
  2177. While cdecl
  2178. Local decl:Object=cdecl.GetDeclList2( ident, declList, maxSearchDepth )
  2179. 'If decl And (Not TFuncDeclList(decl) And declList.IsEmpty()) Return decl
  2180. If decl Then
  2181. declList.AddLast(decl)
  2182. End If
  2183. cdecl=cdecl.superClass
  2184. If maxSearchDepth < SCOPE_CLASS_HEIRARCHY Then
  2185. Exit
  2186. End If
  2187. Wend
  2188. Return declList
  2189. End Method
  2190. 'needs this 'coz you can't go blah.Super.GetDecl()...
  2191. Method GetDeclList2:Object( ident$, declList:TFuncDeclList = Null, maxSearchDepth:Int )
  2192. Return Super.GetDeclList( ident, declList, maxSearchDepth )
  2193. End Method
  2194. Method FindFuncDecl:TFuncDecl( ident$,args:TExpr[] = Null ,explicit:Int=False, isArg:Int = False, isIdentExpr:Int = False, throwOnNotMatched:Int = False, maxSearchDepth:Int )
  2195. ' try the super first...
  2196. Local funcDecl:TFuncDecl = Super.FindFuncDecl(ident, args, explicit, isArg, isIdentExpr, throwOnNotMatched, maxSearchDepth)
  2197. If funcDecl Then
  2198. Return funcDecl
  2199. End If
  2200. If args = Null Then
  2201. args = New TExpr[0]
  2202. End If
  2203. If Not IsInterface()
  2204. ' try getdecl first&
  2205. Local decl:TFuncDecl = TFuncDecl(GetDecl(ident))
  2206. If decl Then
  2207. Return decl
  2208. End If
  2209. Return FindFuncDecl2( ident,args,explicit,isIdentExpr )
  2210. EndIf
  2211. Local fdecl:TFuncDecl=FindFuncDecl2( ident,args,True )
  2212. For Local iface:TClassDecl=EachIn implmentsAll
  2213. Local decl:TFuncDecl=iface.FindFuncDecl2( ident,args,True )
  2214. If Not decl Continue
  2215. If fdecl
  2216. If fdecl.EqualsFunc( decl ) Continue
  2217. Err "Unable to determine overload to use: "+fdecl.ToString()+" or "+decl.ToString()+"."
  2218. EndIf
  2219. fdecl=decl
  2220. Next
  2221. If fdecl Or explicit Return fdecl
  2222. fdecl=FindFuncDecl2( ident,args,False )
  2223. For Local iface:TClassDecl=EachIn implmentsAll
  2224. Local decl:TFuncDecl=iface.FindFuncDecl2( ident,args,False )
  2225. If Not decl Continue
  2226. If fdecl
  2227. If fdecl.EqualsFunc( decl ) Continue
  2228. Err "Unable to determine overload to use: "+fdecl.ToString()+" or "+decl.ToString()+"."
  2229. EndIf
  2230. fdecl=decl
  2231. Next
  2232. Return fdecl
  2233. End Method
  2234. Method FindFuncDecl2:TFuncDecl( ident$,args:TExpr[],explicit:Int, isIdentExpr:Int = False )
  2235. Return Super.FindFuncDecl( ident,args,explicit,,isIdentExpr,0,0 )
  2236. End Method
  2237. Method GetAllFuncDecls:TFuncDecl[](funcs:TFuncDecl[] = Null, includeSuper:Int = True)
  2238. If Not funcs Then
  2239. funcs = New TFuncDecl[0]
  2240. End If
  2241. If superClass And includeSuper Then
  2242. funcs = superClass.GetAllFuncDecls(funcs)
  2243. End If
  2244. ' interface methods
  2245. For Local iface:TClassDecl=EachIn implmentsAll
  2246. funcs = iface.GetAllFuncDecls(funcs)
  2247. Next
  2248. For Local func:TFuncDecl = EachIn _decls
  2249. Local matched:Int = False
  2250. For Local i:Int = 0 Until funcs.length
  2251. ' found a match - we are overriding it
  2252. If func.IdentLower() = funcs[i].IdentLower() And func.EqualsArgs(funcs[i]) Then
  2253. matched = True
  2254. ' but don't override if we are an interface and the function is implemented
  2255. If IsInterface() And Not funcs[i].ClassScope().IsInterface() Then
  2256. Exit
  2257. End If
  2258. ' set this to our own func
  2259. funcs[i] = func
  2260. Exit
  2261. End If
  2262. Next
  2263. If Not matched Then
  2264. funcs :+ [func]
  2265. End If
  2266. Next
  2267. Return funcs
  2268. End Method
  2269. ' returns a list of original function decls (i.e. decls in the scope of their original declarations).
  2270. ' this is useful for generating vtables for extern types
  2271. Method GetAllOriginalFuncDecls:TFuncDecl[](funcs:TFuncDecl[] = Null, includeSuper:Int = True)
  2272. If Not funcs Then
  2273. funcs = New TFuncDecl[0]
  2274. End If
  2275. If superClass And includeSuper Then
  2276. funcs = superClass.GetAllOriginalFuncDecls(funcs, True)
  2277. End If
  2278. ' interface methods
  2279. For Local iface:TClassDecl=EachIn implmentsAll
  2280. For Local func:TFuncDecl=EachIn iface._decls
  2281. Local matched:Int = False
  2282. ' For Local i:Int = 0 Until funcs.length
  2283. ' ' found a match - we are overriding it
  2284. ' If func.IdentLower() = funcs[i].IdentLower() Then
  2285. ' matched = True
  2286. ' Exit
  2287. ' End If
  2288. ' Next
  2289. If Not matched Then
  2290. funcs :+ [func]
  2291. End If
  2292. Next
  2293. Next
  2294. For Local func:TFuncDecl = EachIn _decls
  2295. Local matched:Int = False
  2296. ' dont count any that are already in the funcs list
  2297. For Local i:Int = 0 Until funcs.length
  2298. ' found a match - we are overriding it
  2299. If func.IdentLower() = funcs[i].IdentLower() And func.EqualsArgs(funcs[i]) Then
  2300. matched = True
  2301. ' set this to our own func
  2302. 'funcs[i] = func
  2303. Exit
  2304. End If
  2305. Next
  2306. If Not matched Then
  2307. funcs :+ [func]
  2308. End If
  2309. Next
  2310. Return funcs
  2311. End Method
  2312. Method GetOriginalFuncDecl:TFuncDecl(fdecl:TFuncDecl)
  2313. If Not TClassDecl(Self) Then
  2314. Return fdecl
  2315. End If
  2316. If superClass Then
  2317. Local decl:TFuncDecl = superClass.GetOriginalFuncDecl(fdecl)
  2318. If decl <> fdecl Then
  2319. Return decl
  2320. End If
  2321. End If
  2322. For Local func:TFuncDecl = EachIn _decls
  2323. If func.IdentLower() = fdecl.IdentLower() And func.EqualsArgs(fdecl) Then
  2324. Return func
  2325. End If
  2326. Next
  2327. Return fdecl
  2328. End Method
  2329. Method GetLatestFuncDecl:TFuncDecl(fdecl:TFuncDecl)
  2330. If Not TClassDecl(Self) Then
  2331. Return fdecl
  2332. End If
  2333. For Local func:TFuncDecl = EachIn _decls
  2334. If func.IdentLower() = fdecl.IdentLower() And func.EqualsArgs(fdecl) Then
  2335. Return func
  2336. End If
  2337. Next
  2338. If superClass Then
  2339. Local decl:TFuncDecl = superClass.GetLatestFuncDecl(fdecl)
  2340. If decl <> fdecl Then
  2341. Return decl
  2342. End If
  2343. End If
  2344. Return fdecl
  2345. End Method
  2346. Method ExtendsClass:Int( cdecl:TClassDecl )
  2347. 'If Self=nullObjectClass Return True
  2348. ' If cdecl.IsTemplateArg()
  2349. ' cdecl=TType.objectType.FindClass()
  2350. ' EndIf
  2351. Local tdecl_:TClassDecl=Self
  2352. While tdecl_
  2353. If tdecl_=cdecl Return True
  2354. If cdecl.IsInterface()
  2355. For Local iface:TClassDecl=EachIn tdecl_.implmentsAll
  2356. If iface=cdecl Return True
  2357. Next
  2358. EndIf
  2359. tdecl_=tdecl_.superClass
  2360. Wend
  2361. Return False
  2362. End Method
  2363. Method OnSemant()
  2364. If args Then
  2365. Return
  2366. End If
  2367. PushEnv Self
  2368. 'If Not IsTemplateInst()
  2369. ' For Local i:Int=0 Until args.Length
  2370. ' InsertDecl args[i]
  2371. ' args[i].Semant
  2372. ' Next
  2373. 'EndIf
  2374. 'Semant superclass
  2375. If superTy
  2376. Local cb:TClassDeclCallback = New TClassDeclCallback
  2377. cb.decl = Self
  2378. attrs :| DECL_CYCLIC
  2379. superClass=superTy.SemantClass(cb)
  2380. If superClass.attrs & DECL_CYCLIC Then
  2381. Err "Cyclic type dependency"
  2382. End If
  2383. attrs :~ DECL_CYCLIC
  2384. If superClass.IsInterface() Then
  2385. If Not IsExtern() Or Not superClass.IsExtern() Err superClass.ToString()+" is an interface, not a class."
  2386. If (IsExtern() And Not superClass.IsExtern()) Or (superClass.IsExtern() And Not IsExtern()) Err "Extern and non extern types cannot be mixed."
  2387. End If
  2388. If superClass.IsFinal() Err "Final types cannot be extended."
  2389. EndIf
  2390. 'Semant implemented interfaces
  2391. Local impls:TClassDecl[]=New TClassDecl[impltys.Length]
  2392. Local implsall:TStack=New TStack
  2393. For Local i:Int=0 Until impltys.Length
  2394. attrs :| DECL_CYCLIC
  2395. Local cdecl:TClassDecl=impltys[i].SemantClass()
  2396. attrs :~ DECL_CYCLIC
  2397. If Not cdecl.IsInterface()
  2398. Err cdecl.ToString()+" is a type, not an interface."
  2399. EndIf
  2400. For Local j:Int=0 Until i
  2401. If impls[j]=cdecl
  2402. Err "Duplicate interface "+cdecl.ToString()+"."
  2403. EndIf
  2404. Next
  2405. impls[i]=cdecl
  2406. implsall.Push cdecl
  2407. For Local tdecl_:TDecl=EachIn cdecl.implmentsAll
  2408. implsall.Push tdecl_
  2409. Next
  2410. Next
  2411. Local length:Int = implsall.Length()
  2412. implmentsAll=New TClassDecl[length]
  2413. For Local i:Int=0 Until length
  2414. implmentsAll[i]=TClassDecl(implsall.Get(length - i - 1))
  2415. Next
  2416. implments=impls
  2417. Rem
  2418. If IsInterface()
  2419. 'add implemented methods to our methods
  2420. For Local iface:=EachIn implmentsAll
  2421. For Local decl:=EachIn iface.FuncDecls
  2422. InsertAlias decl.ident,decl
  2423. Next
  2424. Next
  2425. EndIf
  2426. EndRem
  2427. ' attrs|=DECL_SEMANTED
  2428. PopEnv
  2429. 'If IsTemplateArg()
  2430. ' actual=TType.objectType.FindClass()
  2431. ' Return
  2432. 'EndIf
  2433. 'If IsTemplateInst()
  2434. ' Return
  2435. 'EndIf
  2436. If Not lastOffset And superClass Then
  2437. lastOffset = superClass.LastOffset
  2438. End If
  2439. For Local decl:TFieldDecl=EachIn _decls
  2440. GetFieldOffset(decl)
  2441. Next
  2442. If Not IsExtern() And Not IsInterface()
  2443. Local fdecl:TFuncDecl
  2444. For Local decl:TFuncDecl=EachIn FuncDecls()
  2445. If Not decl.IsCtor() Continue
  2446. Local nargs:Int
  2447. For Local arg:TArgDecl=EachIn decl.argDecls
  2448. If Not arg.init nargs:+1
  2449. Next
  2450. If nargs Continue
  2451. fdecl=decl
  2452. Exit
  2453. Next
  2454. ' Don't need default new?
  2455. 'If Not fdecl
  2456. ' fdecl=New TFuncDecl.CreateF( "new",New TObjectType.Create( Self ),Null,FUNC_CTOR )
  2457. ' fdecl.AddStmt New TReturnStmt.Create( Null )
  2458. ' InsertDecl fdecl
  2459. 'EndIf
  2460. EndIf
  2461. For Local decl:TDecl=EachIn _decls
  2462. If TClassDecl(decl) Then
  2463. TClassDecl(decl).Semant
  2464. End If
  2465. Next
  2466. 'NOTE: do this AFTER super semant so UpdateAttrs order is cool.
  2467. If AppScope() Then
  2468. AppScope().semantedClasses.AddLast Self
  2469. End If
  2470. End Method
  2471. Method SemantParts()
  2472. ' If IsSemanted() Return
  2473. ' Super.Semant()
  2474. If args Then
  2475. Return
  2476. End If
  2477. For Local decl:TConstDecl = EachIn Decls()
  2478. decl.Semant()
  2479. Next
  2480. For Local decl:TGlobalDecl = EachIn Decls()
  2481. decl.Semant()
  2482. Next
  2483. ' NOTE : we can't semant functions here as they cause cyclic errors.
  2484. For Local decl:TFuncDecl = EachIn Decls()
  2485. decl.Semant()
  2486. Next
  2487. For Local decl:TFieldDecl = EachIn Decls()
  2488. decl.Semant()
  2489. Next
  2490. ' nested classes
  2491. For Local decl:TClassDecl = EachIn Decls()
  2492. decl.Semant()
  2493. Next
  2494. End Method
  2495. 'Ok, this dodgy looking beast 'resurrects' methods that may not currently be alive, but override methods that ARE.
  2496. Method UpdateLiveMethods:Int()
  2497. If IsInterface() Return 0
  2498. If Not superClass Return 0
  2499. Local n:Int
  2500. For Local decl:TFuncDecl=EachIn MethodDecls()
  2501. If decl.IsSemanted() Continue
  2502. Local live:Int
  2503. Local unsem:TList=New TList'<TFuncDecl>
  2504. unsem.AddLast decl
  2505. Local sclass:TClassDecl=superClass
  2506. While sclass
  2507. For Local decl2:TFuncDecl=EachIn sclass.MethodDecls( decl.ident )
  2508. If decl2.IsSemanted()
  2509. live=True
  2510. Else
  2511. unsem.AddLast decl2
  2512. If decl2.IsExtern() live=True
  2513. If decl2.actual.IsSemanted() live=True
  2514. EndIf
  2515. Next
  2516. sclass=sclass.superClass
  2517. Wend
  2518. If Not live
  2519. Local cdecl:TClassDecl=Self
  2520. While cdecl
  2521. For Local iface:TClassDecl=EachIn cdecl.implmentsAll
  2522. For Local decl2:TFuncDecl=EachIn iface.MethodDecls( decl.ident )
  2523. If decl2.IsSemanted()
  2524. live=True
  2525. Else
  2526. unsem.AddLast decl2
  2527. If decl2.IsExtern() live=True
  2528. If decl2.actual.IsSemanted() live=True
  2529. EndIf
  2530. Next
  2531. Next
  2532. cdecl=cdecl.superClass
  2533. Wend
  2534. EndIf
  2535. If Not live Continue
  2536. For Local decl:TDecl=EachIn unsem
  2537. decl.Semant
  2538. n:+1
  2539. Next
  2540. Next
  2541. Return n
  2542. End Method
  2543. Method FinalizeClass()
  2544. SemantParts()
  2545. PushErr errInfo
  2546. If Not IsInterface()
  2547. ' BlitzMax types are promoted to Abstract if they have an abstract method
  2548. If Not IsAbstract()
  2549. For Local fdecl:TFuncDecl = EachIn GetAllFuncDecls()
  2550. If fdecl.IsMethod() And fdecl.IsAbstract()
  2551. attrs:|DECL_ABSTRACT
  2552. End If
  2553. Next
  2554. End If
  2555. ' Check we implement all abstract methods!
  2556. If IsInstanced()
  2557. For Local fdecl:TFuncDecl = EachIn GetAllFuncDecls()
  2558. If fdecl.IsAbstract() Then
  2559. Err "Can't create instance of type "+ToString()+" due to abstract "+fdecl.ToString()+"."
  2560. End If
  2561. Next
  2562. EndIf
  2563. '
  2564. 'Check we implement all interface methods!
  2565. '
  2566. If Not IsAbstract() Then
  2567. Local ints:TMap = GetInterfaces()
  2568. For Local iface:TClassDecl=EachIn ints.Values()
  2569. If (Not IsExtern() And iface.IsExtern()) Or (IsExtern() And Not iface.IsExtern()) Then
  2570. Err "Cannot mix Extern and non Extern Types and Interfaces."
  2571. End If
  2572. For Local decl:TFuncDecl=EachIn iface.SemantedMethods()
  2573. Local found:Int
  2574. Local voidReturnTypeFail:Int
  2575. Local cdecl:TClassDecl=Self
  2576. While cdecl And Not found
  2577. For Local decl2:TFuncDecl=EachIn cdecl.SemantedMethods( decl.ident )
  2578. ' equals (or extends - for object types)
  2579. If decl2.EqualsFunc( decl )
  2580. If Not decl2.IsPublic() Then
  2581. ' error on function decl
  2582. PushErr decl2.errInfo
  2583. Err TFuncDecl.PrivilegeError(decl2, decl)
  2584. End If
  2585. found=True
  2586. Exit
  2587. Else
  2588. If decl2.EqualsArgs( decl, False ) Then
  2589. If TVoidType(decl.retType) And TIntType(decl2.retType) Then
  2590. ' if we are only strict, we may fail on type mismatch
  2591. If Not ModuleScope().IsSuperStrict() Then
  2592. ' we have the option of upgrading our return type to match superstrict parent
  2593. If Not opt_strictupgrade Then
  2594. voidReturnTypeFail = True
  2595. End If
  2596. End If
  2597. End If
  2598. End If
  2599. EndIf
  2600. Next
  2601. cdecl = cdecl.superClass
  2602. Wend
  2603. If Not found
  2604. Local errorDetails:String = decl.ToString() + " must be implemented by type " + ToString()
  2605. If voidReturnTypeFail Then
  2606. errorDetails :+ " You may have Strict type overriding SuperStrict type. "
  2607. End If
  2608. Err errorDetails
  2609. EndIf
  2610. Next
  2611. Next
  2612. End If
  2613. Else
  2614. ' check for compatible overloads, etc.
  2615. Local impls:TList=New TList
  2616. CheckInterface(Self, impls)
  2617. EndIf
  2618. PopErr
  2619. End Method
  2620. Method CheckInterface(cdecl:TClassDecl, impls:TList)
  2621. While cdecl
  2622. For Local decl:TFuncDecl=EachIn cdecl.SemantedMethods()
  2623. Local found:Int
  2624. For Local decl2:TFuncDecl=EachIn impls
  2625. If decl.IdentLower() = decl2.IdentLower()
  2626. If decl2.argDecls.Length = decl.argDecls.Length And Not decl2.EqualsFunc( decl )
  2627. ' Err "Cannot mix incompatible method signatures." + decl2.ToString() + " vs " + decl.ToString() + "."
  2628. Else
  2629. found = True
  2630. End If
  2631. EndIf
  2632. Next
  2633. If Not found Then
  2634. impls.AddLast decl
  2635. End If
  2636. 'EndIf
  2637. Next
  2638. For Local idecl:TClassDecl = EachIn cdecl.implments
  2639. CheckInterface(idecl, impls)
  2640. Next
  2641. cdecl=cdecl.superClass
  2642. Wend
  2643. End Method
  2644. Method GetFieldOffset(decl:TFieldDecl)
  2645. Local ty:TType = decl.declTy
  2646. Local modifier:Int = POINTER_SIZE
  2647. If TIntType(ty) Or TFloatType(ty) Or TUIntType(ty) Then
  2648. modifier = 4
  2649. Else If TShortType(ty) Then
  2650. modifier = 2
  2651. Else If TLongType(ty) Or TDoubleType(ty) Or TULongType(ty) Then
  2652. modifier = 8
  2653. Else If TByteType(ty) Then
  2654. modifier = 1
  2655. Else If TSizeTType(ty) Then
  2656. modifier = WORD_SIZE
  2657. End If
  2658. If modifier > 1 And lastOffset Mod modifier Then
  2659. lastOffset :+ modifier - (lastOffset Mod modifier)
  2660. End If
  2661. decl.offset = lastOffset
  2662. lastOffset :+ modifier
  2663. End Method
  2664. Method ImplementsInterface:Int(ident:String)
  2665. ident = ident.ToLower()
  2666. For Local iface:TClassDecl = EachIn implmentsAll
  2667. If iface.IdentLower() = ident Then
  2668. Return True
  2669. End If
  2670. Next
  2671. ' check hierarchy
  2672. If superClass Then
  2673. Return superClass.ImplementsInterface(ident)
  2674. End If
  2675. Return False
  2676. End Method
  2677. ' returns a map of all interfaces implemented in this hierarchy
  2678. Method GetInterfaces:TMap(map:TMap = Null)
  2679. If Not map Then
  2680. map = New TMap
  2681. End If
  2682. For Local iface:TClassDecl=EachIn implmentsAll
  2683. If iface.IsInterface() Then
  2684. Local cdecl:TClassDecl = iface
  2685. While cdecl
  2686. If cdecl.IsInterface() Then
  2687. If Not map.Contains(cdecl) Then
  2688. map.Insert(cdecl, cdecl)
  2689. End If
  2690. End If
  2691. cdecl=cdecl.superClass
  2692. Wend
  2693. End If
  2694. Next
  2695. If superClass Then
  2696. map = superClass.GetInterfaces(map)
  2697. End If
  2698. Return map
  2699. End Method
  2700. Method GetImplementedFuncs:TList(list:TList = Null)
  2701. If Not list Then
  2702. list = New TList
  2703. End If
  2704. For Local idecl:TClassDecl = EachIn implmentsAll
  2705. idecl.GetImplementedFuncs(list)
  2706. Next
  2707. For Local decl:TFuncDecl = EachIn SemantedMethods()
  2708. list.AddLast(decl)
  2709. Next
  2710. Return list
  2711. End Method
  2712. End Type
  2713. Type TLoopLabelDecl Extends TDecl ' also used internally for Try constructs
  2714. Field realIdent:String
  2715. Method Create:TLoopLabelDecl( ident$, attrs:Int=0 )
  2716. Self.ident="#" + ident
  2717. Self.realIdent = ident
  2718. Self.attrs=attrs
  2719. Return Self
  2720. End Method
  2721. Method OnCopy:TDecl(deep:Int = True)
  2722. Return New TLoopLabelDecl.Create( realIdent,attrs )
  2723. End Method
  2724. Method OnSemant()
  2725. End Method
  2726. End Type
  2727. Type TDataLabelDecl Extends TDecl
  2728. Field realIdent:String
  2729. Field index:Int
  2730. Method Create:TDataLabelDecl( ident$, attrs:Int=0 )
  2731. Self.ident="#" + ident
  2732. Self.realIdent = ident
  2733. Self.attrs=attrs
  2734. Return Self
  2735. End Method
  2736. Method OnCopy:TDecl(deep:Int = True)
  2737. Return New TDataLabelDecl.Create( realIdent,attrs )
  2738. End Method
  2739. Method OnSemant()
  2740. End Method
  2741. End Type
  2742. Type TDefDataDecl Extends TDecl
  2743. Global count:Int
  2744. Field label:TDataLabelDecl
  2745. Field data:TExpr[]
  2746. Method Create:TDefDataDecl(data:TExpr[], label:TDataLabelDecl = Null, attrs:Int=0 )
  2747. Self.data=data
  2748. Self.label=label
  2749. Self.attrs=attrs
  2750. Return Self
  2751. End Method
  2752. Method OnCopy:TDecl(deep:Int = True)
  2753. Return New TDefDataDecl.Create(TExpr.CopyArgs(data),TDataLabelDecl(label.Copy()),attrs)
  2754. End Method
  2755. Method OnSemant()
  2756. If data Then
  2757. If label Then
  2758. label.index = count
  2759. End If
  2760. For Local i:Int = 0 Until data.length
  2761. data[i] = data[i].Semant()
  2762. If Not TConstExpr(data[i]) Then
  2763. Err "Data items must be numeric or strings"
  2764. Else
  2765. ' todo : more type tests?
  2766. End If
  2767. count :+ 1
  2768. Next
  2769. Else
  2770. ' err?
  2771. End If
  2772. End Method
  2773. End Type
  2774. Type TTryStmtDecl Extends TBlockDecl
  2775. Field tryStmt:TTryStmt
  2776. Method ToString:String()
  2777. Return "TTryStmtDecl"
  2778. End Method
  2779. End Type
  2780. Type TEnumDecl Extends TScopeDecl
  2781. Field ty:TType
  2782. Field isFlags:Int
  2783. Field values:TEnumValueDecl[]
  2784. Method Create:TEnumDecl(id:String, ty:TType, isFlags:Int, values:TEnumValueDecl[])
  2785. Self.ident = id
  2786. Self.ty = ty
  2787. Self.isFlags = isFlags
  2788. Self.values = values
  2789. Return Self
  2790. End Method
  2791. Method OnSemant()
  2792. ' validate type
  2793. If Not TIntegralType(ty) Then
  2794. Err "Invalid type '" + ty.ToString() + "'. Enums can only be declared as integral types."
  2795. End If
  2796. For Local val:TEnumValueDecl = EachIn values
  2797. val.scope = Self
  2798. val.Semant()
  2799. Next
  2800. GenerateFuncs()
  2801. End Method
  2802. Method OnCopy:TDecl(deep:Int = True)
  2803. Return New TEnumDecl.Create(ident, ty, isFlags, values)
  2804. End Method
  2805. Method GetDecl:Object( ident$ )
  2806. For Local val:TEnumValueDecl = EachIn values
  2807. If val.IdentLower() = ident And val.IsSemanted() Then
  2808. Return val
  2809. End If
  2810. Next
  2811. Return Super.GetDecl(ident)
  2812. End Method
  2813. Method GenerateFuncs()
  2814. Local fdecl:TFuncDecl = New TFuncDecl.CreateF("ToString", New TStringType, Null, FUNC_METHOD)
  2815. InsertDecl fdecl
  2816. fdecl.Semant()
  2817. fdecl = New TFuncDecl.CreateF("Ordinal", ty, Null, FUNC_METHOD)
  2818. InsertDecl fdecl
  2819. fdecl.Semant()
  2820. fdecl = New TFuncDecl.CreateF("Values", New TArrayType.Create(New TEnumType.Create(Self), 1), Null, 0)
  2821. InsertDecl fdecl
  2822. fdecl.Semant()
  2823. End Method
  2824. Method ToString:String()
  2825. Return ident
  2826. End Method
  2827. End Type
  2828. Type TEnumValueDecl Extends TDecl
  2829. Field expr:TExpr
  2830. Field index:Int
  2831. Method Create:TEnumValueDecl(id:String, index:Int, expr:TExpr)
  2832. Self.ident = id
  2833. Self.index = index
  2834. Self.expr = expr
  2835. Return Self
  2836. End Method
  2837. Method OnSemant()
  2838. Local parent:TEnumDecl = TEnumDecl(scope)
  2839. Local previous:TEnumValueDecl
  2840. If index > 0 Then
  2841. previous = parent.values[index - 1]
  2842. End If
  2843. If expr Then
  2844. expr = expr.Semant()
  2845. '
  2846. If TIdentEnumExpr(expr) Then
  2847. If TIdentEnumExpr(expr).value.scope = parent Then
  2848. expr = New TConstExpr.Create(parent.ty, TIdentEnumExpr(expr).value.Value()).Semant()
  2849. End If
  2850. End If
  2851. If parent.isFlags And TBinaryMathExpr(expr) Then
  2852. expr = New TConstExpr.Create(parent.ty, TBinaryMathExpr(expr).Eval())
  2853. End If
  2854. If Not TConstExpr(expr) Or Not TIntegralType(TConstExpr(expr).ty) Then
  2855. Err "Enum values must be integral constants."
  2856. End If
  2857. Else
  2858. Local val:Long
  2859. ' initial flags value
  2860. If index = 0 And parent.isFlags Then
  2861. val = 1
  2862. End If
  2863. If previous Then
  2864. '
  2865. If TConstExpr(previous.expr)
  2866. val = TConstExpr(previous.expr).value.ToLong()
  2867. If parent.isFlags Then
  2868. If val = 0 Then
  2869. val = 1
  2870. Else
  2871. If (val & (val - 1)) = 0 Then
  2872. val :+ 1
  2873. End If
  2874. ' find next power of 2
  2875. Local res:Long
  2876. bmx_enum_next_power(Asc(TypeCode(parent.ty)), val, res)
  2877. If Not res Then
  2878. Err "Flags out of bounds at '" + ident + "'."
  2879. End If
  2880. val = res
  2881. End If
  2882. Else
  2883. val :+ 1
  2884. End If
  2885. Else
  2886. InternalErr "TEnumValueDecl.OnSemant"
  2887. End If
  2888. End If
  2889. expr = New TConstExpr.Create( parent.ty.Copy(), val).Semant()
  2890. End If
  2891. End Method
  2892. Method OnCopy:TDecl(deep:Int = True)
  2893. Return New TEnumValueDecl.Create(ident, index, expr)
  2894. End Method
  2895. Method Value:String()
  2896. Return TConstExpr(expr).value
  2897. End Method
  2898. Method TypeCode:String(ty:TType)
  2899. If TByteType( ty ) Return "b"
  2900. If TShortType( ty ) Return "s"
  2901. If TIntType( ty ) Return "i"
  2902. If TUIntType( ty ) Return "u"
  2903. If TLongType( ty ) Return "l"
  2904. If TULongType( ty ) Return "y"
  2905. If TSizeTType( ty ) Return "z"
  2906. End Method
  2907. Method ToString:String()
  2908. Return "TEnumValueDecl"
  2909. End Method
  2910. End Type
  2911. Const MODULE_STRICT:Int=1
  2912. Const MODULE_SUPERSTRICT:Int=2
  2913. Const MODULE_ACTUALMOD:Int=4
  2914. Type TNamespaceDecl Extends TScopeDecl
  2915. ' Field mods:TMap = New TMap
  2916. Method Create:TNamespaceDecl( ident$,munged$ )
  2917. Self.ident=ident
  2918. Self.munged=munged
  2919. Return Self
  2920. End Method
  2921. ' Method GetDecl:Object( ident$ )
  2922. ' Return mods.ValueForKey(ident.ToLower())
  2923. ' End Method
  2924. End Type
  2925. Type TModuleDecl Extends TScopeDecl
  2926. Field filepath$
  2927. Field relpath$
  2928. Field imported:TUnorderedMap=New TUnorderedMap'<TModuleDecl> 'Maps filepath to modules
  2929. Field pubImported:TUnorderedMap =New TUnorderedMap'<TModuleDecl> 'Ditto for publicly imported modules
  2930. Field pmod:TModuleDecl
  2931. Field fileImports:TList=New TList'StringList
  2932. ' cache of ModuleInfo lines
  2933. Field modInfo:TList = New TList
  2934. Field _getDeclTreeCache:TList
  2935. Field _getDeclCache:TMap = New TMap
  2936. Field _getDeclListCache:TMap = New TMap
  2937. Method ToString$()
  2938. Return "Module "+munged
  2939. End Method
  2940. Method Create:TModuleDecl( ident$,munged$,filepath$,attrs:Int )
  2941. Self.ident=ident
  2942. Self.munged=munged
  2943. Self.filepath=filepath
  2944. Self.attrs=attrs
  2945. If ident.Find(".") <> -1 And ident.find("/") = -1 And ident.find("\") = -1 Then
  2946. Local m:String = ident[..ident.Find(".")]
  2947. Local ns:TNamespaceDecl = TNamespaceDecl(_appInstance.GetDecl(m.ToLower()))
  2948. If Not ns Then
  2949. ns = New TNamespaceDecl.Create(m, m)
  2950. If _appInstance.mainModule Then
  2951. _appInstance.mainModule.InsertDecl(ns)
  2952. Else
  2953. ' this must be the main module...
  2954. InsertDecl(ns)
  2955. End If
  2956. End If
  2957. ns.InsertDecl(Self)
  2958. End If
  2959. Return Self
  2960. End Method
  2961. Method UpdateFilePath(fp:String)
  2962. filepath = fp
  2963. End Method
  2964. Method AddImport(imp:String, obj:Object)
  2965. imported.Insert(imp, obj)
  2966. FlushCaches()
  2967. End Method
  2968. Method FlushCaches()
  2969. _getDeclTreeCache = Null
  2970. If TModuleDecl(pmod) Then
  2971. TModuleDecl(pmod).FlushCaches()
  2972. End If
  2973. End Method
  2974. Method IsStrict:Int()
  2975. Return (attrs & MODULE_STRICT)<>0
  2976. End Method
  2977. Method IsSuperStrict:Int()
  2978. Return (attrs & MODULE_SUPERSTRICT)<>0
  2979. End Method
  2980. Method IsActualModule:Int()
  2981. Return (attrs & MODULE_ACTUALMOD)<>0
  2982. End Method
  2983. Method GetDecl:Object( ident$ )
  2984. ' if we previously found it, return it from the cache
  2985. Local decl:Object = _getDeclCache.ValueForKey(ident)
  2986. If decl Then
  2987. Return decl
  2988. End If
  2989. If _getDeclTreeCache Then
  2990. Local declmod$
  2991. For Local mdecl:TModuleDecl = EachIn _getDeclTreeCache
  2992. If ident = mdecl.ident And mdecl <> Self
  2993. _getDeclCache.Insert(ident, mdecl)
  2994. Return mdecl
  2995. End If
  2996. Local tdecl_:Object=mdecl.GetDecl2( ident )
  2997. If tdecl_ And tdecl_<>decl
  2998. If mdecl=Self
  2999. _getDeclCache.Insert(ident, tdecl_)
  3000. Return tdecl_
  3001. End If
  3002. If decl
  3003. Err "Duplicate identifier '"+ident+"' found in module '"+declmod+"' and module '"+mdecl.ident+"'."
  3004. EndIf
  3005. decl=tdecl_
  3006. declmod=mdecl.ident
  3007. EndIf
  3008. Next
  3009. Else
  3010. _getDeclTreeCache = New TList
  3011. Local todo:TList=New TList'<TModuleDecl>
  3012. 'Local done:TIntMap=New TIntMap'<TModuleDecl>
  3013. Local done:TMap = New TMap
  3014. todo.AddLast Self
  3015. 'done.Insert _filePathId,Self
  3016. done.Insert filePath,Self
  3017. Local declmod$
  3018. While Not todo.IsEmpty()
  3019. Local mdecl:TModuleDecl=TModuleDecl(todo.RemoveLast())
  3020. _getDeclTreeCache.AddLast(mdecl)
  3021. Local imps:TUnorderedMap=mdecl.imported
  3022. For Local mdecl2:TModuleDecl=EachIn imps.Values()
  3023. 'If Not done.Contains( mdecl2._filePathId )
  3024. If Not done.Contains( mdecl2.filePath )
  3025. todo.AddLast mdecl2
  3026. 'done.Insert mdecl2._filePathId,mdecl2
  3027. done.Insert mdecl2.filePath,mdecl2
  3028. EndIf
  3029. Next
  3030. Wend
  3031. Return GetDecl(ident)
  3032. End If
  3033. ' cache it for next time
  3034. _getDeclCache.Insert(ident, decl)
  3035. Return decl
  3036. End Method
  3037. Method GetDecl2:Object( ident$ )
  3038. Return Super.GetDecl( ident )
  3039. End Method
  3040. Method GetDeclList:Object( ident$, declList:TFuncDeclList = Null, maxSearchDepth:Int )
  3041. If Not declList Then
  3042. declList = New TFuncDeclList
  3043. End If
  3044. Local decl:Object,declmod$
  3045. If _getDeclTreeCache Then
  3046. ' Print " Using Cache"
  3047. Local declmod$
  3048. For Local mdecl:TModuleDecl = EachIn _getDeclTreeCache
  3049. If ident = mdecl.ident
  3050. '_getDeclCache.Insert(identId, mdecl)
  3051. Return mdecl
  3052. End If
  3053. Local tdecl_:Object=mdecl.GetDeclList2( ident, declList, maxSearchDepth )
  3054. If tdecl_ And tdecl_<>decl
  3055. If mdecl=Self
  3056. _getDeclCache.Insert(ident, tdecl_)
  3057. Return tdecl_
  3058. End If
  3059. If decl
  3060. Err "Duplicate identifier '"+ident+"' found in module '"+declmod+"' and module '"+mdecl.ident+"'."
  3061. EndIf
  3062. decl=tdecl_
  3063. declmod=mdecl.ident
  3064. EndIf
  3065. Next
  3066. Else
  3067. _getDeclTreeCache = New TList
  3068. Local todo:TList=New TList'<TModuleDecl>
  3069. Local done:TMap=New TMap'<TModuleDecl>
  3070. todo.AddLast Self
  3071. done.Insert filepath,Self
  3072. 'Local decl:Object,declmod$
  3073. While Not todo.IsEmpty()
  3074. Local mdecl:TModuleDecl=TModuleDecl(todo.RemoveLast())
  3075. _getDeclTreeCache.AddLast(mdecl)
  3076. Local imps:TUnorderedMap=mdecl.imported
  3077. For Local mdecl2:TModuleDecl=EachIn imps.Values()
  3078. If Not done.Contains( mdecl2.filepath )
  3079. todo.AddLast mdecl2
  3080. done.Insert mdecl2.filepath,mdecl2
  3081. EndIf
  3082. Next
  3083. Wend
  3084. Return GetDeclList( ident, declList, maxSearchDepth )
  3085. End If
  3086. Return decl
  3087. End Method
  3088. Method GetDeclList2:Object( ident$, declList:TFuncDeclList = Null, maxSearchDepth:Int )
  3089. Return Super.GetDeclList( ident, declList, maxSearchDepth )
  3090. End Method
  3091. Method OnSemant()
  3092. Local decl:TFuncDecl = FindFuncDecl( "__localmain", ,,,,,SCOPE_MODULE )
  3093. If decl Then
  3094. decl.Semant
  3095. End If
  3096. For Local gdecl:TGlobalDecl=EachIn _decls
  3097. gdecl.Semant
  3098. Next
  3099. For Local cdecl:TClassDecl=EachIn _decls
  3100. If cdecl.args Then
  3101. For Local inst:TClassDecl = EachIn cdecl.instances
  3102. For Local idecl:TDecl = EachIn inst.Decls()
  3103. If TAliasDecl( idecl ) Continue
  3104. idecl.Semant()
  3105. Next
  3106. Next
  3107. Else
  3108. cdecl.Semant
  3109. End If
  3110. Next
  3111. For Local fdecl:TFuncDecl=EachIn _decls
  3112. fdecl.Semant
  3113. Next
  3114. For Local cdecl:TConstDecl=EachIn _decls
  3115. cdecl.Semant
  3116. Next
  3117. End Method
  3118. End Type
  3119. Type TAppDecl Extends TScopeDecl
  3120. Field imported:TUnorderedMap=New TUnorderedMap'<TModuleDecl> 'maps modpath->mdecl
  3121. Field globalImports:TUnorderedMap = New TUnorderedMap
  3122. Field mainModule:TModuleDecl
  3123. Field mainFunc:TFuncDecl
  3124. Field semantedClasses:TList=New TList'<TClassDecl> 'in-order (ie: base before derived) list of _semanted classes
  3125. Field semantedGlobals:TList=New TList'<TGlobalDecl> 'in-order (ie: dependancy sorted) list of _semanted globals
  3126. Field fileImports:TList=New TList'StringList
  3127. Field headers:TList = New TList
  3128. Field stringConsts:TMap = New TMap
  3129. Field stringConstCount:Int
  3130. Field incbins:TList = New TList
  3131. Field genIncBinHeader:Int = False
  3132. Field dataDefs:TList = New TList
  3133. Field scopeDefs:TMap = New TMap
  3134. Field exportDefs:TList = New TList
  3135. Method GetPathPrefix:String()
  3136. If opt_buildtype = BUILDTYPE_MODULE Then
  3137. Local prefix:String
  3138. Local path:String[] = mainModule.filepath.split("/")
  3139. Local c:Int = 0
  3140. For Local dir:String = EachIn path
  3141. If c Then
  3142. prefix :+ dir.Replace(".mod", "") + "_"
  3143. c:- 1
  3144. End If
  3145. If dir = "mod" Then
  3146. c = 2
  3147. End If
  3148. Next
  3149. Else
  3150. Return "bb_"
  3151. End If
  3152. End Method
  3153. Method InsertModule( mdecl:TModuleDecl )
  3154. mdecl.scope=Self
  3155. imported.Insert mdecl.filepath,mdecl
  3156. If Not mainModule
  3157. mainModule=mdecl
  3158. EndIf
  3159. End Method
  3160. Method IsImported:Int(modpath:String)
  3161. Return globalImports.Contains(modpath)
  3162. End Method
  3163. Method GetDecl:Object( ident$ )
  3164. Local obj:Object = Super.GetDecl(ident)
  3165. If Not obj And mainModule Then
  3166. Return mainModule.GetDecl(ident)
  3167. End If
  3168. Return obj
  3169. End Method
  3170. Method OnSemant()
  3171. 'DebugStop
  3172. _env=Null
  3173. pushenv Self
  3174. SemantDataDefs()
  3175. mainModule.Semant
  3176. mainFunc=mainModule.FindFuncDecl( "__localmain",,,,,,SCOPE_MODULE )
  3177. ' FIXME
  3178. If Not mainFunc Err "Function 'Main' not found."
  3179. SemantDecls()
  3180. Repeat
  3181. Local more:Int
  3182. For Local cdecl:TClassDecl=EachIn semantedClasses
  3183. more:+cdecl.UpdateLiveMethods()
  3184. Next
  3185. If Not more Exit
  3186. Forever
  3187. For Local cdecl:TClassDecl=EachIn semantedClasses
  3188. cdecl.FinalizeClass
  3189. Next
  3190. End Method
  3191. Method SemantDataDefs()
  3192. TDefDataDecl.count = 0
  3193. For Local decl:TDecl = EachIn dataDefs
  3194. decl.Semant
  3195. Next
  3196. End Method
  3197. Method SemantDecls()
  3198. For Local decl:TDecl=EachIn mainModule._decls
  3199. decl.Semant
  3200. ' consts
  3201. Local cdecl:TConstDecl=TConstDecl( decl )
  3202. If cdecl
  3203. cdecl.Semant()
  3204. Continue
  3205. End If
  3206. ' classes
  3207. Local tdecl:TClassDecl=TClassDecl( decl )
  3208. If tdecl
  3209. tdecl.Semant()
  3210. tdecl.SemantParts()
  3211. Continue
  3212. EndIf
  3213. ' functions
  3214. Local fdecl:TFuncDecl=TFuncDecl( decl )
  3215. If fdecl And fdecl <> _appInstance.mainFunc Then
  3216. fdecl.Semant()
  3217. Continue
  3218. End If
  3219. ' globals
  3220. Local gdecl:TGlobalDecl=TGlobalDecl( decl )
  3221. If gdecl
  3222. gdecl.Semant()
  3223. Continue
  3224. End If
  3225. Next
  3226. End Method
  3227. Method hasStringConst:Int(value:String)
  3228. Return stringConsts.ValueForKey(value) <> Null
  3229. End Method
  3230. Method mapStringConsts(value:String)
  3231. Local sc:TStringConst = TStringConst(stringConsts.ValueForKey(value))
  3232. If Not sc Then
  3233. Local sc:TStringConst = New TStringConst
  3234. sc.count = 1
  3235. If value Then
  3236. sc.id = "_s" + stringConstCount
  3237. Else
  3238. sc.id = "bbEmptyString"
  3239. End If
  3240. stringConsts.Insert(value, sc)
  3241. If value Then
  3242. stringConstCount:+ 1
  3243. End If
  3244. Else
  3245. sc.count :+ 1
  3246. End If
  3247. End Method
  3248. Method removeStringConst(value:String)
  3249. If value Then
  3250. Local sc:TStringConst = TStringConst(stringConsts.ValueForKey(value))
  3251. If sc Then
  3252. If sc.count > 0 Then
  3253. sc.count :- 1
  3254. 'stringConsts.Remove(value)
  3255. End If
  3256. End If
  3257. End If
  3258. End Method
  3259. Method FindDataLabel:TDecl(ident:String)
  3260. For Local dd:TDefDataDecl = EachIn dataDefs
  3261. If dd.label And dd.label.ident.ToLower() = ident.ToLower() Then
  3262. Return dd
  3263. End If
  3264. Next
  3265. End Method
  3266. End Type
  3267. Type TStringConst
  3268. Field id:String
  3269. Field count:Int
  3270. End Type
  3271. Type TTemplateDets
  3272. Field instArgs:TType[]
  3273. Field args:TTemplateArg[]
  3274. Method Create:TTemplateDets(instArgs:TType[], args:TTemplateArg[])
  3275. Self.instArgs = instArgs
  3276. Self.args = args
  3277. Return Self
  3278. End Method
  3279. End Type
  3280. Type TGenProcessor Abstract
  3281. Global processor:TGenProcessor
  3282. Method ParseGeneric:Object(templ:TTemplateRecord, dets:TTemplateDets)
  3283. End Method
  3284. End Type