decl.bmx 93 KB

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