decl.bmx 109 KB

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