decl.bmx 115 KB

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