decl.bmx 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752
  1. 'SuperStrict
  2. Const DECL_EXTERN:Int= $010000
  3. Const DECL_PRIVATE:Int= $020000
  4. Const DECL_ABSTRACT:Int= $040000
  5. Const DECL_FINAL:Int= $080000
  6. Const DECL_SEMANTED:Int= $100000
  7. Const DECL_SEMANTING:Int= $200000
  8. Const DECL_POINTER:Int= $400000
  9. Const CLASS_INTERFACE:Int= $001000
  10. Const CLASS_THROWABLE:Int= $002000
  11. Global _env:TScopeDecl
  12. Global _envStack:TList=New TList
  13. Global _appInstance:TAppDecl
  14. Global _loopnest:Int
  15. Function PushEnv( env:TScopeDecl )
  16. If _env _envStack.AddLast( _env )
  17. _env=env
  18. End Function
  19. Function PopEnv()
  20. _env=TScopeDecl( _envStack.RemoveLast() )
  21. End Function
  22. Type TFuncDeclList Extends TList
  23. End Type
  24. Type TDecl
  25. Field ident$
  26. Field munged$
  27. Field errInfo$
  28. Field actual:TDecl
  29. Field scope:TScopeDecl
  30. Field attrs:Int
  31. Field declImported:Int = False
  32. Method New()
  33. errInfo=_errInfo
  34. actual=Self
  35. End Method
  36. Method OnCopy:TDecl() Abstract
  37. Method ToString$()
  38. If TClassDecl( scope ) Return scope.ToString()+"."+ident
  39. Return ident
  40. End Method
  41. Method IsExtern:Int()
  42. Return (attrs & DECL_EXTERN)<>0
  43. End Method
  44. Method IsPrivate:Int()
  45. Return (attrs & DECL_PRIVATE)<>0
  46. End Method
  47. Method IsAbstract:Int()
  48. Return (attrs & DECL_ABSTRACT)<>0
  49. End Method
  50. Method IsSemanted:Int()
  51. Return (attrs & DECL_SEMANTED)<>0
  52. End Method
  53. Method IsSemanting:Int()
  54. Return (attrs & DECL_SEMANTING)<>0
  55. End Method
  56. Method FuncScope:TFuncDecl()
  57. If TFuncDecl( Self ) Return TFuncDecl( Self )
  58. If scope Return scope.FuncScope()
  59. End Method
  60. Method ClassScope:TClassDecl()
  61. If TClassDecl( Self ) Return TClassDecl( Self )
  62. If scope Return scope.ClassScope()
  63. End Method
  64. Method ModuleScope:TModuleDecl()
  65. If TModuleDecl( Self ) Return TModuleDecl( Self )
  66. If scope Return scope.ModuleScope()
  67. End Method
  68. Method AppScope:TAppDecl()
  69. If TAppDecl( Self ) Return TAppDecl( Self )
  70. If scope Return scope.AppScope()
  71. End Method
  72. Method CheckAccess:Int()
  73. If IsPrivate() And ModuleScope()<>_env.ModuleScope() Return False
  74. Return True
  75. End Method
  76. Method AssertAccess()
  77. If Not CheckAccess()
  78. Err ToString() +" is private."
  79. EndIf
  80. End Method
  81. Method Copy:TDecl()
  82. Local t:TDecl=OnCopy()
  83. t.munged=munged
  84. t.errInfo=errInfo
  85. Return t
  86. End Method
  87. Method Semant()
  88. 'DebugStop
  89. If IsSemanted() Return
  90. 'DebugLog "Semant : " + ident
  91. If IsSemanting() Err "Cyclic declaration of '"+ident+"'."
  92. If actual<>Self
  93. actual.Semant
  94. EndIf
  95. PushErr errInfo
  96. If scope
  97. PushEnv scope
  98. EndIf
  99. attrs:|DECL_SEMANTING
  100. 'If ident And ClassScope() Print "Semanting "+ToString()
  101. OnSemant
  102. attrs:&~DECL_SEMANTING
  103. attrs:|DECL_SEMANTED
  104. If scope
  105. 'If Not IsExtern()
  106. If TFuncDecl(Self) And attrs & FUNC_PTR
  107. DebugLog "**** " + ident
  108. Else
  109. scope._semanted.AddLast Self
  110. If TGlobalDecl( Self )
  111. ' FIXME
  112. If AppScope() Then
  113. AppScope().semantedGlobals.AddLast TGlobalDecl( Self )
  114. End If
  115. EndIf
  116. If TModuleDecl( scope )
  117. 'DebugStop
  118. ' FIXME
  119. Local app:TAppDecl = AppScope()
  120. If app Then
  121. app._semanted.AddLast Self
  122. End If
  123. EndIf
  124. EndIf
  125. PopEnv
  126. EndIf
  127. PopErr
  128. End Method
  129. Method InitInstance:TDecl( decl:TDecl )
  130. decl.ident=ident
  131. decl.munged=munged
  132. decl.errInfo=errInfo
  133. decl.actual=actual
  134. decl.scope=Null
  135. decl.attrs=attrs & ~(DECL_SEMANTED|DECL_SEMANTING)
  136. Return decl
  137. End Method
  138. Method GenInstance:TDecl()
  139. InternalErr
  140. End Method
  141. Method OnSemant() Abstract
  142. End Type
  143. Type TValDecl Extends TDecl
  144. 'pre-semant
  145. Field declTy:TType
  146. Field declInit:TExpr
  147. 'post-semant
  148. Field ty:TType
  149. Field init:TExpr
  150. Method ToString$()
  151. Local t$=Super.ToString()
  152. If ty Return t+":"+ty.ToString()
  153. If declTy Return t+":"+declTy.ToString()
  154. Return t+":?"
  155. End Method
  156. Method CopyInit:TExpr()
  157. If init Return init.Copy()
  158. End Method
  159. Method OnSemant()
  160. If declTy
  161. ty=declTy.Semant()
  162. If declInit init=declInit.Copy().SemantAndCast(ty)
  163. Else If declInit
  164. init=declInit.Copy().Semant()
  165. ty=init.exprType
  166. Else
  167. InternalErr
  168. EndIf
  169. End Method
  170. End Type
  171. Type TConstDecl Extends TValDecl
  172. Field value$
  173. Method Create:TConstDecl( ident$,ty:TType,init:TExpr,attrs:Int )
  174. Self.ident=ident
  175. Self.munged=ident
  176. Self.declTy=ty
  177. Self.declInit=init
  178. Self.attrs=attrs
  179. Return Self
  180. End Method
  181. Method GenInstance:TDecl()
  182. Local inst:TConstDecl = New TConstDecl
  183. InitInstance inst
  184. inst.declTy=declTy
  185. inst.declInit=declInit
  186. Return inst
  187. End Method
  188. Method OnCopy:TDecl()
  189. Return New TConstDecl.Create( ident,ty,CopyInit(), attrs )
  190. End Method
  191. Method OnSemant()
  192. Super.OnSemant()
  193. 'If Not IsExtern() value=init.Eval()
  194. If init Then
  195. value=init.Eval()
  196. End If
  197. End Method
  198. End Type
  199. Type TVarDecl Extends TValDecl
  200. End Type
  201. Type TLocalDecl Extends TVarDecl
  202. Method Create:TLocalDecl( ident$,ty:TType,init:TExpr,attrs:Int=0 )
  203. Self.ident=ident
  204. Self.declTy=ty
  205. Self.declInit=init
  206. Self.attrs=attrs
  207. Return Self
  208. End Method
  209. Method OnCopy:TDecl()
  210. Return New TLocalDecl.Create( ident,ty,CopyInit(),attrs )
  211. End Method
  212. Method ToString$()
  213. Return "Local "+Super.ToString()
  214. End Method
  215. End Type
  216. Type TArgDecl Extends TLocalDecl
  217. Field castTo:String
  218. Method Create:TArgDecl( ident$,ty:TType,init:TExpr,attrs:Int=0 )
  219. Self.ident=ident
  220. Self.declTy=ty
  221. Self.declInit=init
  222. Self.attrs=attrs
  223. Return Self
  224. End Method
  225. Method GenInstance:TDecl()
  226. Local inst:TArgDecl=New TArgDecl
  227. InitInstance inst
  228. inst.declTy=declTy
  229. inst.declInit=declInit
  230. Return inst
  231. End Method
  232. Method OnCopy:TDecl()
  233. Return New TArgDecl.Create( ident,ty,CopyInit(),attrs )
  234. End Method
  235. Method ToString$()
  236. Return Super.ToString()
  237. End Method
  238. End Type
  239. Type TGlobalDecl Extends TVarDecl
  240. Method Create:TGlobalDecl( ident$,ty:TType,init:TExpr,attrs:Int=0 )
  241. Self.ident=ident
  242. Self.declTy=ty
  243. Self.declInit=init
  244. Self.attrs=attrs
  245. Return Self
  246. End Method
  247. Method OnCopy:TDecl()
  248. Return New TGlobalDecl.Create( ident,ty,CopyInit(),attrs )
  249. End Method
  250. Method ToString$()
  251. Return "Global "+Super.ToString()
  252. End Method
  253. Method GenInstance:TDecl()
  254. ' PushErr errInfo
  255. ' Err "Global variables cannot be used inside generic classes."
  256. Local inst:TGlobalDecl=New TGlobalDecl
  257. InitInstance inst
  258. inst.declTy=declTy
  259. inst.declInit=declInit
  260. Return inst
  261. End Method
  262. End Type
  263. Type TFieldDecl Extends TVarDecl
  264. ' location offset in object variable data
  265. Field offset:Int
  266. Method Create:TFieldDecl( ident$,ty:TType,init:TExpr,attrs:Int=0 )
  267. Self.ident=ident
  268. Self.declTy=ty
  269. Self.declInit=init
  270. Self.attrs=attrs
  271. Return Self
  272. End Method
  273. Method OnCopy:TDecl()
  274. Return New TFieldDecl.Create( ident,ty,CopyInit(),attrs )
  275. End Method
  276. Method ToString$()
  277. Return "Field "+Super.ToString()
  278. End Method
  279. Method GenInstance:TDecl()
  280. Local inst:TFieldDecl=New TFieldDecl
  281. InitInstance inst
  282. inst.declTy=declTy
  283. inst.declInit=declInit
  284. Return inst
  285. End Method
  286. End Type
  287. Type TAliasDecl Extends TDecl
  288. Field decl:Object
  289. Method Create:TAliasDecl( ident$,decl:Object,attrs:Int=0 )
  290. Self.ident=ident
  291. Self.decl=decl
  292. Self.attrs=attrs
  293. Return Self
  294. End Method
  295. Method OnCopy:TDecl()
  296. Return New TAliasDecl.Create( ident,decl,attrs )
  297. End Method
  298. Method OnSemant()
  299. End Method
  300. End Type
  301. Type TScopeDecl Extends TDecl
  302. 'Private
  303. Field _decls:TList=New TList'<TDecl>
  304. Field _semanted:TList=New TList'<TDecl>
  305. Field declsMap:TMap=New TMap'<Object>
  306. 'Public
  307. Method OnCopy:TDecl()
  308. InternalErr
  309. End Method
  310. Method Decls:TList()
  311. Return _decls
  312. End Method
  313. Method Semanted:TList()
  314. Return _semanted
  315. End Method
  316. Method FuncDecls:TList( id$="" )
  317. Local fdecls:TList=New TList
  318. For Local decl:TDecl=EachIn _decls
  319. If id And decl.ident<>id Continue
  320. Local fdecl:TFuncDecl=TFuncDecl( decl )
  321. If fdecl fdecls.AddLast fdecl
  322. Next
  323. Return fdecls
  324. End Method
  325. Method MethodDecls:TList( id$="" )
  326. Local fdecls:TList=New TList
  327. For Local decl:TDecl=EachIn _decls
  328. If id And decl.ident<>id Continue
  329. Local fdecl:TFuncDecl=TFuncDecl( decl )
  330. If fdecl And fdecl.IsMethod() fdecls.AddLast fdecl
  331. Next
  332. Return fdecls
  333. End Method
  334. Method SemantedFuncs:TList( id$="" )
  335. Local fdecls:TList=New TList
  336. For Local decl:TDecl=EachIn _semanted
  337. If id And decl.ident<>id Continue
  338. Local fdecl:TFuncDecl=TFuncDecl( decl )
  339. If fdecl fdecls.AddLast fdecl
  340. Next
  341. Return fdecls
  342. End Method
  343. Method SemantedMethods:TList( id$="" )
  344. Local fdecls:TList=New TList
  345. For Local decl:TDecl=EachIn _semanted
  346. If id And decl.ident<>id Continue
  347. Local fdecl:TFuncDecl=TFuncDecl( decl )
  348. If fdecl And fdecl.IsMethod() fdecls.AddLast fdecl
  349. Next
  350. Return fdecls
  351. End Method
  352. Method InsertDecl( decl:TDecl )
  353. If decl.scope InternalErr
  354. Local ident$=decl.ident
  355. If Not ident Return
  356. decl.scope=Self
  357. _decls.AddLast decl
  358. 'Local _decls:TMap
  359. Local tdecl_:Object=declsMap.ValueForKey( ident.ToLower() )
  360. 'If TFuncDecl( decl )
  361. ' Local funcs:TFuncDeclList=TFuncDeclList( tdecl_ )
  362. ' If funcs Or Not tdecl_
  363. ' If Not funcs
  364. ' funcs=New TFuncDeclList
  365. ' declsMap.Insert ident.ToLower(),funcs
  366. ' EndIf
  367. ' funcs.AddLast TFuncDecl( decl )
  368. ' Else
  369. ' Err "Duplicate identifier '"+ident+"'."
  370. ' EndIf
  371. 'Else
  372. If Not tdecl_
  373. 'DebugLog "Adding " + decl.ident
  374. declsMap.Insert ident.ToLower(),decl
  375. Else
  376. Err "Duplicate identifier '"+ident+"'."
  377. EndIf
  378. End Method
  379. Method InsertDecls( _decls:TList )
  380. For Local decl:TDecl=EachIn _decls
  381. InsertDecl decl
  382. Next
  383. End Method
  384. 'This is overridden by TClassDecl and TModuleDecl
  385. Method GetDecl:Object( ident$ )
  386. 'DebugLog "GetDecl (" + Self.ident + ") : " + ident
  387. Local decl:Object=Object(declsMap.ValueForKey( ident.ToLower() ))
  388. If Not decl Then
  389. If Self.ident.ToLower() = ident.ToLower() Then
  390. decl = Self
  391. End If
  392. End If
  393. If Not decl Return Null
  394. Local adecl:TAliasDecl=TAliasDecl( decl )
  395. If Not adecl Return decl
  396. If adecl.CheckAccess() Return adecl.decl
  397. End Method
  398. Method FindDecl:Object( ident$ )
  399. Local decl:Object=GetDecl( ident )
  400. If decl Return decl
  401. If scope Return scope.FindDecl( ident )
  402. End Method
  403. Method FindValDecl:TValDecl( ident$ )
  404. Local decl:TValDecl=TValDecl( FindDecl( ident ) )
  405. If Not decl Return Null
  406. decl.AssertAccess
  407. decl.Semant
  408. Return decl
  409. End Method
  410. Method FindType:TType( ident$,args:TType[] )
  411. Local decl:Object=(GetDecl( ident ))
  412. If decl Then
  413. Local ty:TType=TType(decl)
  414. If ty
  415. If args.Length Err "Wrong number of type arguments"
  416. Return ty
  417. EndIf
  418. Local cdecl:TClassDecl=TClassDecl( decl )
  419. If cdecl
  420. cdecl.AssertAccess
  421. cdecl=cdecl.GenClassInstance( args )
  422. cdecl.Semant
  423. Return cdecl.objectType
  424. EndIf
  425. EndIf
  426. If scope Return scope.FindType( ident,args )
  427. End Method
  428. Method FindScopeDecl:TScopeDecl( ident$ )
  429. Local decl:TScopeDecl=TScopeDecl( FindDecl( ident ) )
  430. If Not decl Return Null
  431. decl.AssertAccess
  432. decl.Semant
  433. Return decl
  434. End Method
  435. Rem
  436. Method FindClassDecl:TClassDecl( ident$,args:TClassDecl[] = Null )
  437. Local decl:TClassDecl=TClassDecl( GetDecl( ident ) )
  438. If Not args Then
  439. args = New TClassDecl[0]
  440. End If
  441. If Not decl
  442. If scope Return scope.FindClassDecl( ident,args )
  443. Return Null
  444. EndIf
  445. decl.AssertAccess
  446. decl.Semant
  447. Return decl.GenClassInstance( args )
  448. End Method
  449. End Rem
  450. Method FindModuleDecl:TModuleDecl( ident$ )
  451. 'DebugStop
  452. Local decl:TModuleDecl=TModuleDecl( GetDecl( ident ) )
  453. If Not decl
  454. If scope Return scope.FindModuleDecl( ident )
  455. Return Null
  456. EndIf
  457. decl.AssertAccess
  458. ' only semant on "real" module
  459. If Not decl.declImported Then
  460. decl.Semant
  461. End If
  462. Return decl
  463. End Method
  464. Method FindFuncDecl:TFuncDecl( ident$,argExprs:TExpr[] = Null,explicit:Int=False )
  465. 'DebugLog "FindFuncDecl : " + ident
  466. 'If ident = "Print" Then DebugStop
  467. 'Local funcs:TFuncDeclList=TFuncDeclList( FindDecl( ident ) )
  468. Local f:TDecl = TDecl(findDecl(ident))
  469. If Not f Then Return Null
  470. Local func:TFuncDecl = TFuncDecl(f)
  471. If Not func Then
  472. If TVarDecl(f) Then
  473. If TFunctionPtrType(TVarDecl(f).ty) Then
  474. func = TFunctionPtrType(TVarDecl(f).ty).func
  475. If Not func.scope Then
  476. func.scope = f.scope
  477. End If
  478. End If
  479. End If
  480. End If
  481. If Not func Return Null
  482. If Not argExprs
  483. argExprs = New TExpr[0]
  484. End If
  485. 'For Local func:TFuncDecl=EachIn funcs
  486. func.Semant()
  487. 'Next
  488. Local match:TFuncDecl,isexact:Int
  489. Local _err$
  490. 'DebugStop
  491. 'For Local func:TFuncDecl=EachIn funcs
  492. While True
  493. If Not func.CheckAccess() Exit
  494. Local argDecls:TArgDecl[]=func.argDecls
  495. If argExprs.Length>argDecls.Length Exit
  496. Local exact:Int=True
  497. Local possible:Int=True
  498. For Local i:Int=0 Until argDecls.Length
  499. If i<argExprs.Length And argExprs[i]
  500. Local declTy:TType=argDecls[i].ty
  501. Local exprTy:TType=argExprs[i].exprType
  502. If exprTy.EqualsType( declTy ) Exit
  503. exact=False
  504. If Not explicit And exprTy.ExtendsType( declTy ) Exit
  505. Else If argDecls[i].init
  506. exact=False
  507. If Not explicit Exit
  508. EndIf
  509. possible=False
  510. Exit
  511. Next
  512. If Not possible Exit
  513. If exact
  514. If isexact
  515. Err "Unable to determine overload to use: "+match.ToString()+" or "+func.ToString()+"."
  516. Else
  517. _err=""
  518. match=func
  519. isexact=True
  520. EndIf
  521. Else
  522. If Not isexact
  523. If match
  524. _err="Unable to determine overload to use: "+match.ToString()+" or "+func.ToString()+"."
  525. Else
  526. match=func
  527. EndIf
  528. EndIf
  529. EndIf
  530. Exit
  531. Wend
  532. If Not isexact
  533. If _err Err _err
  534. If explicit Return Null
  535. EndIf
  536. If Not match
  537. Local t$
  538. For Local i:Int=0 Until argExprs.Length
  539. If t t:+","
  540. If argExprs[i] t:+argExprs[i].exprType.ToString()
  541. Next
  542. Err "Unable to find overload for "+ident+"("+t+")."
  543. EndIf
  544. match.AssertAccess
  545. Return match
  546. End Method
  547. Method OnSemant()
  548. End Method
  549. End Type
  550. Type TBlockDecl Extends TScopeDecl
  551. Field stmts:TList=New TList
  552. Method Create:TBlockDecl( scope:TScopeDecl )
  553. Self.scope=scope
  554. Return Self
  555. End Method
  556. Method AddStmt( stmt:TStmt )
  557. stmts.AddLast stmt
  558. End Method
  559. Method OnCopy:TDecl()
  560. Local t:TBlockDecl=New TBlockDecl
  561. For Local stmt:TStmt=EachIn stmts
  562. t.AddStmt stmt.Copy( t )
  563. Next
  564. Return t
  565. End Method
  566. Method OnSemant()
  567. PushEnv Self
  568. For Local stmt:TStmt=EachIn stmts
  569. stmt.Semant
  570. Next
  571. PopEnv
  572. End Method
  573. Method CopyBlock:TBlockDecl( scope:TScopeDecl )
  574. Local t:TBlockDecl=TBlockDecl( Copy() )
  575. t.scope=scope
  576. Return t
  577. End Method
  578. End Type
  579. Const FUNC_METHOD:Int=1 'mutually exclusive with ctor
  580. Const FUNC_CTOR:Int=2
  581. Const FUNC_PROPERTY:Int=4
  582. Const FUNC_PTR:Int=8
  583. Const FUNC_BUILTIN:Int = $10
  584. 'Fix! A func is NOT a block/scope!
  585. '
  586. Type TFuncDecl Extends TBlockDecl
  587. Field retType:TType
  588. Field retTypeExpr:TType
  589. Field argDecls:TArgDecl[]
  590. Field overrides:TFuncDecl
  591. Field superCtor:TInvokeSuperExpr
  592. Field castTo:String
  593. Field noCastGen:Int
  594. Method CreateF:TFuncDecl( ident$,ty:TType,argDecls:TArgDecl[],attrs:Int )
  595. Self.ident=ident
  596. Self.retTypeExpr=ty
  597. If argDecls
  598. Self.argDecls=argDecls
  599. Else
  600. Self.argDecls = New TArgDecl[0]
  601. End If
  602. Self.attrs=attrs
  603. Return Self
  604. End Method
  605. Method OnCopy:TDecl()
  606. Local args:TArgDecl[]=argDecls[..]
  607. For Local i:Int=0 Until args.Length
  608. args[i]=TArgDecl( args[i].Copy() )
  609. Next
  610. Local t:TFuncDecl=New TFuncDecl.CreateF( ident,retType,args,attrs )
  611. For Local stmt:TStmt=EachIn stmts
  612. t.AddStmt stmt.Copy( t )
  613. Next
  614. Return t
  615. End Method
  616. Method GenInstance:TDecl()
  617. Local inst:TFuncDecl=New TFuncDecl
  618. InitInstance inst
  619. inst.retTypeExpr=retTypeExpr
  620. inst.argDecls=argDecls[..]
  621. For Local i:Int=0 Until argDecls.Length
  622. inst.argDecls[i]=TArgDecl( argDecls[i].GenInstance() )
  623. Next
  624. Return inst
  625. End Method
  626. Method ToString$()
  627. Local t$
  628. For Local decl:TArgDecl=EachIn argDecls
  629. If t t:+","
  630. t:+decl.ToString()
  631. Next
  632. Local q$
  633. If IsCtor()
  634. q="Method "+Super.ToString()
  635. Else
  636. If IsMethod() q="Method " Else q="Function "
  637. q:+Super.ToString()+":"
  638. If retType
  639. q:+retType.ToString()
  640. Else If retTypeExpr
  641. q:+retTypeExpr.ToString()
  642. Else
  643. q:+"?"
  644. EndIf
  645. EndIf
  646. Return q+"("+t+")"
  647. End Method
  648. Method IsBuiltIn:Int()
  649. Return (attrs & FUNC_BUILTIN)<>0
  650. End Method
  651. Method IsCtor:Int()
  652. Return (attrs & FUNC_CTOR)<>0
  653. End Method
  654. Method IsMethod:Int()
  655. Return (attrs & FUNC_METHOD)<>0
  656. End Method
  657. Method IsStatic:Int()
  658. Return (attrs & (FUNC_METHOD|FUNC_CTOR))=0
  659. End Method
  660. Method IsProperty:Int()
  661. Return (attrs & FUNC_PROPERTY)<>0
  662. End Method
  663. Method EqualsArgs:Int( decl:TFuncDecl )
  664. If argDecls.Length<>decl.argDecls.Length Return False
  665. For Local i:Int=0 Until argDecls.Length
  666. If Not argDecls[i].ty.EqualsType( decl.argDecls[i].ty ) Return False
  667. Next
  668. Return True
  669. End Method
  670. Method EqualsFunc:Int( decl:TFuncDecl )
  671. Return retType.EqualsType( decl.retType ) And EqualsArgs( decl )
  672. End Method
  673. Method OnSemant()
  674. 'semant ret type
  675. If Not retTypeExpr Then
  676. retType = TType.voidType
  677. Else
  678. retType=retTypeExpr.Semant()
  679. End If
  680. If TArrayType( retType ) And Not retType.EqualsType( retType.ActualType() )
  681. ' Err "Return type cannot be an array of generic objects."
  682. EndIf
  683. 'semant args
  684. For Local arg:TArgDecl=EachIn argDecls
  685. InsertDecl arg
  686. arg.Semant
  687. Next
  688. If actual<>Self Return
  689. 'check for duplicate decl
  690. For Local decl:TFuncDecl=EachIn scope.SemantedFuncs( ident )
  691. If decl<>Self And EqualsArgs( decl )
  692. Err "Duplicate declaration "+ToString()
  693. EndIf
  694. Next
  695. 'get cdecl, sclasss
  696. Local cdecl:TClassDecl=ClassScope(),sclass:TClassDecl
  697. If cdecl sclass=TClassDecl( cdecl.superClass )
  698. 'prefix call to super ctor if necessary
  699. If IsCtor() And superCtor=Null
  700. If sclass.FindFuncDecl( "new", Null )
  701. superCtor=New TInvokeSuperExpr.Create( "new" )
  702. stmts.AddFirst New TExprStmt.Create( superCtor )
  703. EndIf
  704. EndIf
  705. 'append a return statement if necessary
  706. If Not IsExtern() And Not TVoidType( retType ) And Not TReturnStmt( stmts.Last() )
  707. Local stmt:TReturnStmt
  708. If IsCtor()
  709. stmt=New TReturnStmt.Create( Null )
  710. Else
  711. stmt=New TReturnStmt.Create( New TConstExpr.Create( retType,"" ) )
  712. EndIf
  713. stmt.errInfo=errInfo
  714. stmts.AddLast stmt
  715. EndIf
  716. 'check we exactly match an override
  717. If sclass And IsMethod()
  718. 'DebugStop
  719. 'DebugLog ident + "..."
  720. While sclass
  721. 'DebugLog "Checking " + sclass.ident
  722. Local found:Int
  723. For Local decl:TFuncDecl=EachIn sclass.MethodDecls( )
  724. 'DebugLog "Method = " + decl.ident
  725. If Not decl.IsSemanted() Then
  726. decl.Semant
  727. End If
  728. If decl.ident = ident Then
  729. found=True
  730. If EqualsFunc( decl )
  731. 'DebugLog "Found"
  732. overrides=TFuncDecl( decl.actual )
  733. 'If overrides.munged
  734. ' If munged And munged<>overrides.munged
  735. ' InternalErr
  736. ' EndIf
  737. ' munged=overrides.munged
  738. 'EndIf
  739. EndIf
  740. End If
  741. Next
  742. If found
  743. If Not overrides Err "Overriding method does not match any overridden method."
  744. Exit
  745. EndIf
  746. sclass=sclass.superClass
  747. Wend
  748. EndIf
  749. 'If ident = "OnDebugStop" DebugStop
  750. attrs:|DECL_SEMANTED
  751. Super.OnSemant()
  752. End Method
  753. End Type
  754. 'Const CLASS_INTERFACE:Int=1
  755. 'Const CLASS_TEMPLATEARG:Int=2
  756. 'Const CLASS_TEMPLATEINST:Int=4
  757. 'Const CLASS_INSTANCED:Int=8 'class used in New?
  758. Const CLASS_INSTANCED:Int=1
  759. Const CLASS_EXTENDSOBJECT:Int=2
  760. Const CLASS_FINALIZED:Int=4
  761. Type TNullDecl Extends TClassDecl
  762. End Type
  763. Type TClassDecl Extends TScopeDecl
  764. Field lastOffset:Int
  765. Field args:TClassDecl[]
  766. Field superTy:TIdentType
  767. Field impltys:TIdentType[]
  768. Field superClass:TClassDecl
  769. Field implments:TClassDecl[] 'interfaces immediately implemented
  770. Field implmentsAll:TClassDecl[] 'all interfaces implemented
  771. Field instanceof:TClassDecl 'for instances
  772. Field instances:TList 'for actual (non-arg, non-instance)
  773. Field instArgs:TType[]
  774. Field objectType:TObjectType '"canned" objectType
  775. Global nullObjectClass:TClassDecl=New TNullDecl.Create( "{NULL}",Null,Null,Null,DECL_ABSTRACT|DECL_EXTERN )
  776. Method Create:TClassDecl( ident$,args:TClassDecl[],superTy:TIdentType,impls:TIdentType[],attrs:Int )
  777. Self.ident=ident
  778. Self.args=args
  779. Self.superTy=superTy
  780. Self.impltys=impls
  781. Self.attrs=attrs
  782. Self.objectType=New TObjectType.Create( Self )
  783. If args
  784. instances=New TList
  785. instances.AddLast Self
  786. EndIf
  787. Return Self
  788. End Method
  789. Method OnCopy:TDecl()
  790. InternalErr
  791. End Method
  792. Method ToString$()
  793. Local t$
  794. If args Then
  795. For Local i:Int=0 Until args.Length
  796. If i t:+","
  797. t:+args[i].ToString()
  798. Next
  799. ElseIf instargs
  800. End If
  801. If t t="<"+t+">"
  802. Return ident+t
  803. End Method
  804. Rem
  805. Method GenClassInstance:TClassDecl( instArgs:TClassDecl[] )
  806. If Not IsSemanted() InternalErr
  807. 'no args
  808. If Not instArgs
  809. If Not args Return Self
  810. If instanceof Return Self
  811. For Local inst:TClassDecl=EachIn instances
  812. If _env.ClassScope()=inst Return inst
  813. Next
  814. EndIf
  815. 'If Not instanceof And Not instArgs Return Self
  816. 'check number of args
  817. If instanceof Or args.Length<>instArgs.Length
  818. Err "Wrong number of class arguments for "+ToString()
  819. EndIf
  820. 'look for existing instance
  821. For Local inst:TClassDecl=EachIn instances
  822. Local equal:Int=True
  823. For Local i:Int=0 Until args.Length
  824. If inst.args[i]=instArgs[i] Continue
  825. equal=False
  826. Exit
  827. Next
  828. If equal Return inst
  829. Next
  830. Local inst:TClassDecl=New TClassDecl
  831. InitInstance inst
  832. inst.scope=scope
  833. inst.attrs:|CLASS_TEMPLATEINST
  834. inst.args=instArgs
  835. inst.superTy=superTy
  836. inst.instanceof=Self
  837. instances.AddLast inst
  838. For Local i:Int=0 Until args.Length
  839. inst.InsertDecl New TAliasDecl.Create( args[i].ident,instArgs[i] )
  840. Next
  841. For Local decl:TDecl=EachIn _decls
  842. If TClassDecl( decl ) Continue
  843. inst.InsertDecl decl.GenInstance()
  844. Next
  845. 'inst.Semant
  846. 'A bit cheeky...
  847. inst.OnSemant
  848. inst.attrs:|DECL_SEMANTED
  849. Return inst
  850. End Method
  851. End Rem
  852. Method GenClassInstance:TClassDecl( instArgs:TType[] )
  853. If instanceof InternalErr
  854. 'no args
  855. If Not instArgs
  856. If Not args Return Self
  857. For Local inst:TClassDecl=EachIn instances
  858. If _env.ClassScope()=inst Return inst
  859. Next
  860. EndIf
  861. 'check number of args
  862. If args.Length<>instArgs.Length
  863. Err "Wrong number of type arguments for class "+ToString()
  864. EndIf
  865. 'look for existing instance
  866. For Local inst:TClassDecl=EachIn instances
  867. Local equal:Int=True
  868. For Local i:Int=0 Until args.Length
  869. If Not inst.instArgs[i].EqualsType( instArgs[i] )
  870. equal=False
  871. Exit
  872. EndIf
  873. Next
  874. If equal Return inst
  875. Next
  876. Local inst:TClassDecl=New TClassDecl.Create( ident,Null,superTy,impltys, attrs )
  877. inst.attrs:&~DECL_SEMANTED
  878. inst.munged=munged
  879. inst.errInfo=errInfo
  880. inst.scope=scope
  881. inst.instanceof=Self
  882. inst.instArgs=instArgs
  883. instances.AddLast inst
  884. For Local i:Int=0 Until args.Length
  885. inst.InsertDecl New TAliasDecl.Create( args[i].ToString(),instArgs[i],0 )
  886. Next
  887. For Local decl:TDecl=EachIn _decls
  888. inst.InsertDecl decl.Copy()
  889. Next
  890. Return inst
  891. End Method
  892. Method IsInterface:Int()
  893. Return (attrs & CLASS_INTERFACE)<>0
  894. End Method
  895. Method IsThrowable:Int()
  896. Return (attrs & CLASS_THROWABLE)<>0
  897. End Method
  898. Method IsFinalized:Int()
  899. Return (attrs & CLASS_FINALIZED)<>0
  900. End Method
  901. Method ExtendsObject:Int()
  902. Return (attrs & CLASS_EXTENDSOBJECT)<>0
  903. End Method
  904. Method IsInstanced:Int()
  905. Return (attrs & CLASS_INSTANCED)<>0
  906. End Method
  907. Method GetDecl:Object( ident$ )
  908. Local cdecl:TClassDecl=Self
  909. While cdecl
  910. Local decl:Object=cdecl.GetDecl2( ident )
  911. If decl Return decl
  912. cdecl=cdecl.superClass
  913. Wend
  914. End Method
  915. 'needs this 'coz you can't go blah.Super.GetDecl()...
  916. Method GetDecl2:Object( ident$ )
  917. Return Super.GetDecl( ident )
  918. End Method
  919. Method FindFuncDecl:TFuncDecl( ident$,args:TExpr[] = Null ,explicit:Int=False )
  920. If args = Null Then
  921. args = New TExpr[0]
  922. End If
  923. If Not IsInterface()
  924. ' try getdecl first&
  925. Local decl:TFuncDecl = TFuncDecl(GetDecl(ident))
  926. If decl Then
  927. Return decl
  928. End If
  929. Return FindFuncDecl2( ident,args,explicit )
  930. EndIf
  931. Local fdecl:TFuncDecl=FindFuncDecl2( ident,args,True )
  932. For Local iface:TClassDecl=EachIn implmentsAll
  933. Local decl:TFuncDecl=iface.FindFuncDecl2( ident,args,True )
  934. If Not decl Continue
  935. If fdecl
  936. If fdecl.EqualsFunc( decl ) Continue
  937. Err "Unable to determine overload to use: "+fdecl.ToString()+" or "+decl.ToString()+"."
  938. EndIf
  939. fdecl=decl
  940. Next
  941. If fdecl Or explicit Return fdecl
  942. fdecl=FindFuncDecl2( ident,args,False )
  943. For Local iface:TClassDecl=EachIn implmentsAll
  944. Local decl:TFuncDecl=iface.FindFuncDecl2( ident,args,False )
  945. If Not decl Continue
  946. If fdecl
  947. If fdecl.EqualsFunc( decl ) Continue
  948. Err "Unable to determine overload to use: "+fdecl.ToString()+" or "+decl.ToString()+"."
  949. EndIf
  950. fdecl=decl
  951. Next
  952. Return fdecl
  953. End Method
  954. Method FindFuncDecl2:TFuncDecl( ident$,args:TExpr[],explicit:Int )
  955. Return Super.FindFuncDecl( ident,args,explicit )
  956. End Method
  957. Method GetAllFuncDecls:TFuncDecl[](funcs:TFuncDecl[] = Null, includeSuper:Int = True)
  958. If Not funcs Then
  959. funcs = New TFuncDecl[0]
  960. End If
  961. If superClass And includeSuper Then
  962. funcs = superClass.GetAllFuncDecls(funcs)
  963. End If
  964. For Local func:TFuncDecl = EachIn _decls
  965. Local matched:Int = False
  966. For Local i:Int = 0 Until funcs.length
  967. ' found a match - we are overriding it
  968. If func.ident.ToLower() = funcs[i].ident.ToLower() Then
  969. matched = True
  970. ' set this to our own func
  971. funcs[i] = func
  972. Exit
  973. End If
  974. Next
  975. If Not matched Then
  976. funcs :+ [func]
  977. End If
  978. Next
  979. Return funcs
  980. End Method
  981. Method ExtendsClass:Int( cdecl:TClassDecl )
  982. If Self=nullObjectClass Return True
  983. ' If cdecl.IsTemplateArg()
  984. ' cdecl=TType.objectType.FindClass()
  985. ' EndIf
  986. Local tdecl_:TClassDecl=Self
  987. While tdecl_
  988. If tdecl_=cdecl Return True
  989. If cdecl.IsInterface()
  990. For Local iface:TClassDecl=EachIn tdecl_.implmentsAll
  991. If iface=cdecl Return True
  992. Next
  993. EndIf
  994. tdecl_=tdecl_.superClass
  995. Wend
  996. Return False
  997. End Method
  998. Method OnSemant()
  999. 'Print "Semanting "+ToString()
  1000. PushEnv Self
  1001. 'If Not IsTemplateInst()
  1002. ' For Local i:Int=0 Until args.Length
  1003. ' InsertDecl args[i]
  1004. ' args[i].Semant
  1005. ' Next
  1006. 'EndIf
  1007. 'Semant superclass
  1008. If superTy
  1009. 'superClass=superTy.FindClass()
  1010. superClass=superTy.SemantClass()
  1011. If superClass.IsInterface() Err superClass.ToString()+" is an interface, not a class."
  1012. EndIf
  1013. 'Semant implemented interfaces
  1014. Local impls:TClassDecl[]=New TClassDecl[impltys.Length]
  1015. Local implsall:TStack=New TStack
  1016. For Local i:Int=0 Until impltys.Length
  1017. Local cdecl:TClassDecl=impltys[i].SemantClass()
  1018. If Not cdecl.IsInterface()
  1019. Err cdecl.ToString()+" is a class, not an interface."
  1020. EndIf
  1021. For Local j:Int=0 Until i
  1022. If impls[j]=cdecl
  1023. Err "Duplicate interface "+cdecl.ToString()+"."
  1024. EndIf
  1025. Next
  1026. impls[i]=cdecl
  1027. implsall.Push cdecl
  1028. For Local tdecl_:TDecl=EachIn cdecl.implmentsAll
  1029. implsall.Push tdecl_
  1030. Next
  1031. Next
  1032. implmentsAll=New TClassDecl[implsall.Length()]
  1033. For Local i:Int=0 Until implsall.Length()
  1034. implmentsAll[i]=TClassDecl(implsall.Get(i))
  1035. Next
  1036. implments=impls
  1037. Rem
  1038. If IsInterface()
  1039. 'add implemented methods to our methods
  1040. For Local iface:=EachIn implmentsAll
  1041. For Local decl:=EachIn iface.FuncDecls
  1042. InsertAlias decl.ident,decl
  1043. Next
  1044. Next
  1045. EndIf
  1046. EndRem
  1047. ' attrs|=DECL_SEMANTED
  1048. PopEnv
  1049. 'If IsTemplateArg()
  1050. ' actual=TType.objectType.FindClass()
  1051. ' Return
  1052. 'EndIf
  1053. 'If IsTemplateInst()
  1054. ' Return
  1055. 'EndIf
  1056. 'Are we abstract?
  1057. If Not IsAbstract()
  1058. For Local decl:TDecl=EachIn _decls
  1059. Local fdecl:TFuncDecl=TFuncDecl( decl )
  1060. If fdecl And fdecl.IsAbstract()
  1061. attrs:|DECL_ABSTRACT
  1062. Exit
  1063. EndIf
  1064. Next
  1065. EndIf
  1066. If Not lastOffset And superClass Then
  1067. lastOffset = superClass.LastOffset
  1068. End If
  1069. For Local decl:TFieldDecl=EachIn _decls
  1070. GetFieldOffset(decl)
  1071. Next
  1072. If Not IsExtern() And Not IsInterface()
  1073. Local fdecl:TFuncDecl
  1074. For Local decl:TFuncDecl=EachIn FuncDecls()
  1075. If Not decl.IsCtor() Continue
  1076. Local nargs:Int
  1077. For Local arg:TArgDecl=EachIn decl.argDecls
  1078. If Not arg.init nargs:+1
  1079. Next
  1080. If nargs Continue
  1081. fdecl=decl
  1082. Exit
  1083. Next
  1084. For Local decl:TConstDecl = EachIn Decls()
  1085. decl.Semant()
  1086. Next
  1087. For Local decl:TGlobalDecl = EachIn Decls()
  1088. decl.Semant()
  1089. Next
  1090. ' Don't need default new?
  1091. 'If Not fdecl
  1092. ' fdecl=New TFuncDecl.CreateF( "new",New TObjectType.Create( Self ),Null,FUNC_CTOR )
  1093. ' fdecl.AddStmt New TReturnStmt.Create( Null )
  1094. ' InsertDecl fdecl
  1095. 'EndIf
  1096. EndIf
  1097. 'NOTE: do this AFTER super semant so UpdateAttrs order is cool.
  1098. If AppScope() Then
  1099. AppScope().semantedClasses.AddLast Self
  1100. End If
  1101. End Method
  1102. 'Ok, this dodgy looking beast 'resurrects' methods that may not currently be alive, but override methods that ARE.
  1103. Method UpdateLiveMethods:Int()
  1104. If IsInterface() Return 0
  1105. If Not superClass Return 0
  1106. Local n:Int
  1107. For Local decl:TFuncDecl=EachIn MethodDecls()
  1108. If decl.IsSemanted() Continue
  1109. Local live:Int
  1110. Local unsem:TList=New TList'<TFuncDecl>
  1111. unsem.AddLast decl
  1112. Local sclass:TClassDecl=superClass
  1113. While sclass
  1114. For Local decl2:TFuncDecl=EachIn sclass.MethodDecls( decl.ident )
  1115. If decl2.IsSemanted()
  1116. live=True
  1117. Else
  1118. unsem.AddLast decl2
  1119. If decl2.IsExtern() live=True
  1120. If decl2.actual.IsSemanted() live=True
  1121. EndIf
  1122. Next
  1123. sclass=sclass.superClass
  1124. Wend
  1125. If Not live
  1126. Local cdecl:TClassDecl=Self
  1127. While cdecl
  1128. For Local iface:TClassDecl=EachIn cdecl.implmentsAll
  1129. For Local decl2:TFuncDecl=EachIn iface.MethodDecls( decl.ident )
  1130. If decl2.IsSemanted()
  1131. live=True
  1132. Else
  1133. unsem.AddLast decl2
  1134. If decl2.IsExtern() live=True
  1135. If decl2.actual.IsSemanted() live=True
  1136. EndIf
  1137. Next
  1138. Next
  1139. cdecl=cdecl.superClass
  1140. Wend
  1141. EndIf
  1142. If Not live Continue
  1143. For Local decl:TDecl=EachIn unsem
  1144. decl.Semant
  1145. n:+1
  1146. Next
  1147. Next
  1148. Return n
  1149. End Method
  1150. Method FinalizeClass()
  1151. PushErr errInfo
  1152. If Not IsInterface()
  1153. '
  1154. 'check for duplicate fields!
  1155. '
  1156. For Local decl:TDecl=EachIn Semanted()
  1157. Local fdecl:TFieldDecl=TFieldDecl( decl )
  1158. If Not fdecl Continue
  1159. Local cdecl:TClassDecl=superClass
  1160. While cdecl
  1161. For Local decl:TDecl=EachIn cdecl.Semanted()
  1162. If decl.ident=fdecl.ident Err "Field '"+fdecl.ident+"' in class "+ToString()+" overrides existing declaration in class "+cdecl.ToString()
  1163. Next
  1164. cdecl=cdecl.superClass
  1165. Wend
  1166. Next
  1167. '
  1168. 'Check we implement all abstract methods!
  1169. '
  1170. If IsInstanced()
  1171. Local cdecl:TClassDecl=Self
  1172. Local impls:TList=New TList'<TFuncDecl>
  1173. While cdecl
  1174. For Local decl:TFuncDecl=EachIn cdecl.SemantedMethods()
  1175. If decl.IsAbstract()
  1176. Local found:Int
  1177. For Local decl2:TFuncDecl=EachIn impls
  1178. If decl.EqualsFunc( decl2 )
  1179. found=True
  1180. Exit
  1181. EndIf
  1182. Next
  1183. If Not found
  1184. Err "Can't create instance of class "+ToString()+" due to abstract method "+decl.ToString()+"."
  1185. EndIf
  1186. Else
  1187. impls.AddLast decl
  1188. EndIf
  1189. Next
  1190. cdecl=cdecl.superClass
  1191. Wend
  1192. EndIf
  1193. '
  1194. 'Check we implement all interface methods!
  1195. '
  1196. For Local iface:TClassDecl=EachIn implmentsAll
  1197. For Local decl:TFuncDecl=EachIn iface.SemantedMethods()
  1198. Local found:Int
  1199. For Local decl2:TFuncDecl=EachIn SemantedMethods( decl.ident )
  1200. If decl.EqualsFunc( decl2 )
  1201. If decl2.munged
  1202. Err "Extern methods cannot be used to implement interface methods."
  1203. EndIf
  1204. found=True
  1205. EndIf
  1206. Next
  1207. If Not found
  1208. Err decl.ToString()+" must be implemented by class "+ToString()
  1209. EndIf
  1210. Next
  1211. Next
  1212. EndIf
  1213. PopErr
  1214. End Method
  1215. Method GetFieldOffset(decl:TFieldDecl)
  1216. Local ty:TType = decl.declTy
  1217. Local modifier:Int = POINTER_SIZE
  1218. If TIntType(ty) Or TFloatType(ty) Then
  1219. modifier = 4
  1220. Else If TShortType(ty) Then
  1221. modifier = 2
  1222. Else If TLongType(ty) Or TDoubleType(ty) Then
  1223. modifier = 8
  1224. Else If TByteType(ty) Then
  1225. modifier = 1
  1226. End If
  1227. If modifier > 1 And lastOffset Mod modifier Then
  1228. lastOffset :+ modifier - (lastOffset Mod modifier)
  1229. End If
  1230. decl.offset = lastOffset
  1231. lastOffset :+ modifier
  1232. End Method
  1233. End Type
  1234. Const MODULE_STRICT:Int=1
  1235. Const MODULE_SUPERSTRICT:Int=2
  1236. Const MODULE_ACTUALMOD:Int=4
  1237. Type TModuleDecl Extends TScopeDecl
  1238. Field filepath$
  1239. Field relpath$
  1240. Field imported:TMap=New TMap'<TModuleDecl> 'Maps filepath to modules
  1241. Field pubImported:TMap=New TMap'<TModuleDecl> 'Ditto for publicly imported modules
  1242. ' cache of ModuleInfo lines
  1243. Field modInfo:TList = New TList
  1244. Method ToString$()
  1245. Return "Module "+munged
  1246. End Method
  1247. Method Create:TModuleDecl( ident$,munged$,filepath$,attrs:Int )
  1248. Self.ident=ident
  1249. Self.munged=munged
  1250. Self.filepath=filepath
  1251. Self.attrs=attrs
  1252. Return Self
  1253. End Method
  1254. Method IsStrict:Int()
  1255. Return (attrs & MODULE_STRICT)<>0
  1256. End Method
  1257. Method IsSuperStrict:Int()
  1258. Return (attrs & MODULE_SUPERSTRICT)<>0
  1259. End Method
  1260. Method IsActualModule:Int()
  1261. Return (attrs & MODULE_ACTUALMOD)<>0
  1262. End Method
  1263. Method GetDecl:Object( ident$ )
  1264. 'DebugLog "GetDecl (" + ident + ") : " + filepath
  1265. Local todo:TList=New TList'<TModuleDecl>
  1266. Local done:TMap=New TMap'<TModuleDecl>
  1267. todo.AddLast Self
  1268. done.Insert filepath,Self
  1269. Local decl:Object,declmod$
  1270. While Not todo.IsEmpty()
  1271. Local mdecl:TModuleDecl=TModuleDecl(todo.RemoveLast())
  1272. Local tdecl_:Object=mdecl.GetDecl2( ident )
  1273. If tdecl_ And tdecl_<>decl
  1274. If mdecl=Self Return tdecl_
  1275. If decl
  1276. Err "Duplicate identifier '"+ident+"' found in module '"+declmod+"' and module '"+mdecl.ident+"'."
  1277. EndIf
  1278. decl=tdecl_
  1279. declmod=mdecl.ident
  1280. EndIf
  1281. 'If Not _env Exit
  1282. Local imps:TMap=mdecl.imported
  1283. 'If mdecl<>_env.ModuleScope() imps=mdecl.pubImported
  1284. For Local mdecl2:TModuleDecl=EachIn imps.Values()
  1285. If Not done.Contains( mdecl2.filepath )
  1286. todo.AddLast mdecl2
  1287. done.Insert mdecl2.filepath,mdecl2
  1288. EndIf
  1289. If ident = mdecl2.ident
  1290. Return mdecl2
  1291. End If
  1292. Next
  1293. Wend
  1294. Return decl
  1295. End Method
  1296. Method GetDecl2:Object( ident$ )
  1297. Return Super.GetDecl( ident )
  1298. End Method
  1299. Method OnSemant()
  1300. For Local gdecl:TGlobalDecl=EachIn _decls
  1301. gdecl.Semant
  1302. Next
  1303. For Local cdecl:TClassDecl=EachIn _decls
  1304. cdecl.Semant
  1305. Next
  1306. For Local fdecl:TFuncDecl=EachIn _decls
  1307. fdecl.Semant
  1308. Next
  1309. For Local cdecl:TConstDecl=EachIn _decls
  1310. cdecl.Semant
  1311. Next
  1312. End Method
  1313. End Type
  1314. Type TAppDecl Extends TScopeDecl
  1315. Field imported:TMap=New TMap'<TModuleDecl> 'maps modpath->mdecl
  1316. Field mainModule:TModuleDecl
  1317. Field mainFunc:TFuncDecl
  1318. Field semantedClasses:TList=New TList'<TClassDecl> 'in-order (ie: base before derived) list of _semanted classes
  1319. Field semantedGlobals:TList=New TList'<TGlobalDecl> 'in-order (ie: dependancy sorted) list of _semanted globals
  1320. Field fileImports:TList=New TList'StringList
  1321. Field stringConsts:TMap = New TMap
  1322. Field stringConstCount:Int
  1323. Method GetPathPrefix:String()
  1324. If opt_buildtype = BUILDTYPE_MODULE Then
  1325. Local prefix:String
  1326. Local path:String[] = mainModule.filepath.split("/")
  1327. Local c:Int = 0
  1328. For Local dir:String = EachIn path
  1329. If c Then
  1330. prefix :+ dir.Replace(".mod", "") + "_"
  1331. c:- 1
  1332. End If
  1333. If dir = "mod" Then
  1334. c = 2
  1335. End If
  1336. Next
  1337. Else
  1338. Return "bb_"
  1339. End If
  1340. End Method
  1341. Method InsertModule( mdecl:TModuleDecl )
  1342. mdecl.scope=Self
  1343. imported.Insert mdecl.filepath,mdecl
  1344. If Not mainModule
  1345. mainModule=mdecl
  1346. EndIf
  1347. End Method
  1348. Method GetDecl:Object( ident$ )
  1349. Local obj:Object = Super.GetDecl(ident)
  1350. If Not obj Then
  1351. Return mainModule.GetDecl(ident)
  1352. End If
  1353. Return obj
  1354. End Method
  1355. Method OnSemant()
  1356. 'DebugStop
  1357. _env=Null
  1358. pushenv Self
  1359. mainModule.Semant
  1360. mainFunc=mainModule.FindFuncDecl( "LocalMain" )
  1361. ' FIXME
  1362. If Not mainFunc Err "Function 'Main' not found."
  1363. 'If Not TIntType( mainFunc.retType ) Or mainFunc.argDecls.Length
  1364. ' Err "Main function must be of type Main:Int()"
  1365. 'EndIf
  1366. Repeat
  1367. Local more:Int
  1368. For Local cdecl:TClassDecl=EachIn semantedClasses
  1369. more:+cdecl.UpdateLiveMethods()
  1370. Next
  1371. If Not more Exit
  1372. Forever
  1373. For Local cdecl:TClassDecl=EachIn semantedClasses
  1374. cdecl.FinalizeClass
  1375. Next
  1376. End Method
  1377. Method mapStringConsts(value:String)
  1378. Local sc:TStringConst = TStringConst(stringConsts.ValueForKey(value))
  1379. If Not sc Then
  1380. Local sc:TStringConst = New TStringConst
  1381. sc.count = 1
  1382. sc.id = "_s" + stringConstCount
  1383. stringConsts.Insert(value, sc)
  1384. stringConstCount:+ 1
  1385. Else
  1386. sc.count :+ 1
  1387. End If
  1388. End Method
  1389. Method removeStringConst(value:String)
  1390. Local sc:TStringConst = TStringConst(stringConsts.ValueForKey(value))
  1391. If sc Then
  1392. sc.count :- 1
  1393. If sc.count = 0 Then
  1394. stringConsts.Remove(value)
  1395. End If
  1396. End If
  1397. End Method
  1398. End Type
  1399. Type TStringConst
  1400. Field id:String
  1401. Field count:Int
  1402. End Type