PageRenderTime 28ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/src/ast3/type.py

https://bitbucket.org/bungcip/pytegal
Python | 211 lines | 206 code | 4 blank | 1 comment | 2 complexity | 25f1ee8108d8372f2d561b5bd50eec0c MD5 | raw file
  1. #!/usr/bin/env python
  2. from utils import factory, joinList, assertImpossible
  3. from node import SymbolNode
  4. import report
  5. @factory
  6. class Type(SymbolNode):
  7. def __init__(self, symbol, typeArgs=[]):
  8. super(Type, self).__init__()
  9. self.symbol = symbol
  10. self.typeArgs = typeArgs
  11. def __str__(self):
  12. classname = self.__class__.__name__.split('Type')[0]
  13. if isinstance(self.symbol, str):
  14. name = self.symbol
  15. else:
  16. name = getattr(self.symbol, 'name', "")
  17. return '{0} {1}'.format(classname, name)
  18. def __eq__(self, other):
  19. if other == None: return False
  20. if self.symbol == other.symbol and self.typeArgs == other.typeArgs:
  21. return True
  22. return False
  23. def __ne__(self, other):
  24. return not self.__eq__(other)
  25. def fits(self, target):
  26. """
  27. Check whether the type can fits to target type.
  28. self fits to target if:
  29. - self == target
  30. - self is subrange of target (e.g: Byte is subrange of Int)
  31. - type A is struct/class instance and type B is interface and
  32. A implements method signature that defined B
  33. - type A is decentdant of type B
  34. """
  35. if self == target: return True
  36. ##FIXME:this is just hack to avoid checking generic type
  37. ## FIX THIS!!!!!
  38. elif isinstance(target, GenericType):
  39. report.info("\tType.fits()::generic type ignored, source = {}".format(self))
  40. return True
  41. elif isinstance(self, Type) and isinstance(target, InterfaceInstType):
  42. if self.symbol.implements(target.symbol):
  43. return True
  44. ##FIXME:for now, just for class
  45. elif isinstance(self, ClassInstType) and isinstance(target, ClassInstType) :
  46. if self.symbol.hasExtend(target.symbol):
  47. return True
  48. return False
  49. class ModuleType(Type):pass
  50. class InterfaceType(Type):pass
  51. class StructType(Type):pass
  52. class ClassType(Type):pass
  53. class EnumType(Type): pass
  54. ### type of symbol which can have instance ############################
  55. class InterfaceInstType(Type):pass
  56. class ClassInstType(Type):
  57. def __str__(self):
  58. return self.symbol.name + joinList(self.typeArgs, begin='!(', end=')')
  59. class StructInstType(Type):
  60. def __str__(self):
  61. ##FIXME: hack when self.symbol is None, actually self.symbol must not None...
  62. name = getattr(self.symbol, 'name', '<Unknown Struct>')
  63. return name + joinList(self.typeArgs, begin='!(', end=')')
  64. class EnumInstType(Type): pass
  65. class DefType(Type):
  66. def __init__(self, loc, genericTypes, paramTypes, returnType):
  67. super(DefType, self).__init__(None)
  68. self.loc = loc
  69. self.genericTypes = genericTypes
  70. self.paramTypes = paramTypes
  71. self.returnType = returnType
  72. def __eq__(self, other):
  73. if isinstance(other, DefType) and self.paramTypes == other.paramTypes and self.returnType == other.returnType:
  74. return True
  75. return False
  76. def __str__(self):
  77. text = '#'
  78. if self.genericTypes:
  79. text += '!({})'.format(joinList(self.genericTypes))
  80. text += "|"
  81. if self.paramTypes:
  82. text += '{}'.format(joinList(self.paramTypes))
  83. if self.returnType:
  84. text += ' -> {}'.format(self.returnType)
  85. text += "|"
  86. return text
  87. def fits(self, target):
  88. if not isinstance(target, DefType): return False
  89. if self.paramTypes != target.paramTypes: return False
  90. if self.returnType == target.returnType: return True
  91. if isinstance(target.returnType, VoidType): return True
  92. assertImpossible("Cannot go to this...")
  93. class NamedParamType(Type):
  94. """ This type intended for parameter in DefType """
  95. def __init__(self, loc, name=None, type=None, default=None, marks=""):
  96. """
  97. __init__(loc, name, type, default=None, marks='')
  98. __init__(param)
  99. """
  100. super(NamedParamType, self).__init__(None)
  101. if hasattr(loc, 'name'):
  102. self.loc = None if getattr(loc, 'src', None) is None else loc.src.loc
  103. self.name = loc.name
  104. self.type = loc.type
  105. self.default = loc.default
  106. self.marks = getattr(loc, 'marks', '')
  107. else:
  108. self.loc = loc
  109. self.name = name
  110. self.type = type
  111. self.default = default
  112. self.marks = marks
  113. def __str__(self):
  114. name = "{} ".format(self.name) if self.name else ""
  115. return "{}{}{}".format(self.marks, name, self.type)
  116. class GenericType(Type):
  117. """ Type that act as proxy for real type when the the owner symbol type instance-niated """
  118. def __init__(self, symbol, owner=None):
  119. """ create generic type from symbol
  120. symbol = TypeParam instance
  121. owner = Symbol which have scope of this GenericType
  122. """
  123. super(GenericType, self).__init__(symbol)
  124. self.owner = owner
  125. def fits(self, target):
  126. report.info("\tGenericType.fits():: ignored, target = {}".format(target))
  127. return True
  128. class AutoType(Type):
  129. def __init__(self, candidates=None):
  130. super(AutoType, self).__init__(None)
  131. self.candidates = candidates
  132. def __str__(self):
  133. return "Auto:{}".format(self.candidates)
  134. class NameType(Type):
  135. def __init__(self, loc, name, typeArgs=[], left=None):
  136. super(NameType, self).__init__(None)
  137. self.loc = loc
  138. self.name = name
  139. self.typeArgs = typeArgs
  140. self.left = left
  141. def __str__(self):
  142. text = ""
  143. if self.left:
  144. text = str(self.left) + '.'
  145. text += self.name
  146. return text
  147. class RangeType(Type):
  148. def __init__(self):
  149. super(RangeType, self).__init__(None)
  150. class VoidType(StructInstType):
  151. def __init__(self):
  152. super(type(self), self).__init__(None)
  153. self.name = "Void"
  154. def fits(self, target):
  155. """ Other type cannot fit VoidType """
  156. return False
  157. class MappedArgType(Type):
  158. def __init__(self, symbol, typeArgs):
  159. assert len(typeArgs) == 2, "len(typeArgs) must be 2 (typeArgs=={0})".format(repr(typeArgs))
  160. super(type(self), self).__init__(symbol, typeArgs)
  161. def __str__(self):
  162. return "{0} => {1}".format(*self.typeArgs)
  163. class ComprehensionType(Type):
  164. def __init__(self, typeArg):
  165. super(ComprehensionType, self).__init__(None, [typeArg])