decl.bmx 118 KB

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