decl.bmx 112 KB

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