decl.bmx 110 KB

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