decl.bmx 110 KB

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