PageRenderTime 45ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/trunk/frege/compiler/TAlias.fr

http://frege.googlecode.com/
Forth | 75 lines | 69 code | 6 blank | 0 comment | 3 complexity | b90c8f71ad9bcac6c104a478847f1cd8 MD5 | raw file
  1. -- enable UTF-8 ŤŤŤŤŤŤŤŤŤŤŤŤŤŤ•••••••••••••ťťťťťťťťťťťťŚŚŚŚŚŚŚŚ
  2. {--
  3. * This is pass 4 of the compiler, implemented in 'pass'.
  4. * We must make sure that *type* definitions are not self-referential
  5. * directly or indirectly.
  6. -}
  7. {-
  8. * $Author: Ingo.Wechsung@googlemail.com $
  9. * $Revision: 525 $
  10. * $Date: 2012-02-21 00:19:03 +0100 (Tue, 21 Feb 2012) $
  11. * $Id: TAlias.fr 525 2012-02-20 23:19:03Z Ingo.Wechsung@googlemail.com $
  12. -}
  13. package frege.compiler.TAlias where
  14. --- This is $Revision: 525 $
  15. protected version = v "$Revision: 525 $" where
  16. v (m ~ #(\d+)#) | Just g <- m.group 1 = g.atoi
  17. v _ = 0
  18. import frege.compiler.Data
  19. import frege.compiler.Nice (msgdoc)
  20. import frege.compiler.Utilities as U()
  21. import frege.compiler.Transdef as T()
  22. import Data.List as DL(partitioned)
  23. --- post condition is true
  24. post = do
  25. stio true
  26. pass = do
  27. g <- getST
  28. let (adefs,other) = partitioned isTypDcl g.definitions
  29. adeps = map aliasdep adefs
  30. agrps = U.tsort adeps
  31. aflat = [ a | grp <- agrps, a <- grp ]
  32. sdefs = [ d | a <- aflat, d <- adefs, QName.base a == Definition.name d ]
  33. isTypDcl (TypDcl {pos}) = true
  34. isTypDcl _ = false
  35. aliasdep (TypDcl {pos, name, rho}) = (tn, filter (flip QName.our g) deps) where
  36. tn = TName g.thisPack name
  37. deps = collectRho rho []
  38. aliasdep x = error "no TypDcl"
  39. collectRho (RhoFun _ sig rho) acc = collectRho rho (collectSigma sig acc)
  40. where
  41. collectSigma (ForAll _ rho) acc = collectRho rho acc
  42. collectRho (RhoTau _ tau) acc = collectTau tau acc
  43. collectTau (TVar _ _) acc = acc
  44. collectTau (Meta _) acc = acc
  45. collectTau (TApp a b) acc = collectTau a (collectTau b acc)
  46. collectTau (TFun a b) acc = collectTau a (collectTau b acc)
  47. collectTau (TCon _ n) acc = case U.nstname n g of
  48. Nothing -> acc
  49. Just tn
  50. | tn `elem` acc = acc
  51. | Just (SymA {name}) <- tn.findit g = if name `elem` acc then acc else name:acc
  52. | otherwise = acc -- do not complain about unknown type constructors
  53. getpos tn
  54. | Just (SymA {pos}) <- QName.findit tn g = pos
  55. | otherwise = Position.null
  56. checkmutual [] = stio ()
  57. checkmutual [a] = stio ()
  58. checkmutual (a:as) = U.error (getpos a) (msgdoc ("Mutual recursive type aliases "
  59. ++ joined ", " (map (flip QName.nice g) (a:as))))
  60. checkselfref (tn, deps)
  61. | tn `elem` deps = U.error (getpos tn) (msgdoc ("Self referential type alias `"
  62. ++ QName.nice tn g ++ "`"))
  63. | otherwise = stio ()
  64. changeST Global.{sub <- SubSt.{definitions=reverse other}} -- no more type aliases henceforth
  65. foreach agrps checkmutual
  66. foreach adeps checkselfref
  67. g <- getST
  68. unless (g.sub.errors > 0) do foreach sdefs (T.transdef [] (VName g.thisPack))
  69. stio ("type aliases", length adefs)