/src/ast3/type.py
Python | 211 lines | 206 code | 4 blank | 1 comment | 2 complexity | 25f1ee8108d8372f2d561b5bd50eec0c MD5 | raw file
- #!/usr/bin/env python
- from utils import factory, joinList, assertImpossible
- from node import SymbolNode
- import report
- @factory
- class Type(SymbolNode):
- def __init__(self, symbol, typeArgs=[]):
- super(Type, self).__init__()
- self.symbol = symbol
- self.typeArgs = typeArgs
- def __str__(self):
- classname = self.__class__.__name__.split('Type')[0]
- if isinstance(self.symbol, str):
- name = self.symbol
- else:
- name = getattr(self.symbol, 'name', "")
- return '{0} {1}'.format(classname, name)
- def __eq__(self, other):
- if other == None: return False
- if self.symbol == other.symbol and self.typeArgs == other.typeArgs:
- return True
- return False
- def __ne__(self, other):
- return not self.__eq__(other)
- def fits(self, target):
- """
- Check whether the type can fits to target type.
- self fits to target if:
- - self == target
- - self is subrange of target (e.g: Byte is subrange of Int)
- - type A is struct/class instance and type B is interface and
- A implements method signature that defined B
- - type A is decentdant of type B
- """
- if self == target: return True
- ##FIXME:this is just hack to avoid checking generic type
- ## FIX THIS!!!!!
- elif isinstance(target, GenericType):
- report.info("\tType.fits()::generic type ignored, source = {}".format(self))
- return True
- elif isinstance(self, Type) and isinstance(target, InterfaceInstType):
- if self.symbol.implements(target.symbol):
- return True
- ##FIXME:for now, just for class
- elif isinstance(self, ClassInstType) and isinstance(target, ClassInstType) :
- if self.symbol.hasExtend(target.symbol):
- return True
- return False
- class ModuleType(Type):pass
- class InterfaceType(Type):pass
- class StructType(Type):pass
- class ClassType(Type):pass
- class EnumType(Type): pass
- ### type of symbol which can have instance ############################
- class InterfaceInstType(Type):pass
- class ClassInstType(Type):
- def __str__(self):
- return self.symbol.name + joinList(self.typeArgs, begin='!(', end=')')
- class StructInstType(Type):
- def __str__(self):
- ##FIXME: hack when self.symbol is None, actually self.symbol must not None...
- name = getattr(self.symbol, 'name', '<Unknown Struct>')
- return name + joinList(self.typeArgs, begin='!(', end=')')
- class EnumInstType(Type): pass
- class DefType(Type):
- def __init__(self, loc, genericTypes, paramTypes, returnType):
- super(DefType, self).__init__(None)
- self.loc = loc
- self.genericTypes = genericTypes
- self.paramTypes = paramTypes
- self.returnType = returnType
- def __eq__(self, other):
- if isinstance(other, DefType) and self.paramTypes == other.paramTypes and self.returnType == other.returnType:
- return True
- return False
- def __str__(self):
- text = '#'
- if self.genericTypes:
- text += '!({})'.format(joinList(self.genericTypes))
- text += "|"
- if self.paramTypes:
- text += '{}'.format(joinList(self.paramTypes))
- if self.returnType:
- text += ' -> {}'.format(self.returnType)
- text += "|"
-
- return text
-
- def fits(self, target):
- if not isinstance(target, DefType): return False
- if self.paramTypes != target.paramTypes: return False
- if self.returnType == target.returnType: return True
- if isinstance(target.returnType, VoidType): return True
-
- assertImpossible("Cannot go to this...")
-
- class NamedParamType(Type):
- """ This type intended for parameter in DefType """
- def __init__(self, loc, name=None, type=None, default=None, marks=""):
- """
- __init__(loc, name, type, default=None, marks='')
- __init__(param)
- """
-
- super(NamedParamType, self).__init__(None)
-
- if hasattr(loc, 'name'):
- self.loc = None if getattr(loc, 'src', None) is None else loc.src.loc
- self.name = loc.name
- self.type = loc.type
- self.default = loc.default
- self.marks = getattr(loc, 'marks', '')
- else:
- self.loc = loc
- self.name = name
- self.type = type
- self.default = default
- self.marks = marks
- def __str__(self):
- name = "{} ".format(self.name) if self.name else ""
- return "{}{}{}".format(self.marks, name, self.type)
- class GenericType(Type):
- """ Type that act as proxy for real type when the the owner symbol type instance-niated """
-
- def __init__(self, symbol, owner=None):
- """ create generic type from symbol
- symbol = TypeParam instance
- owner = Symbol which have scope of this GenericType
- """
-
- super(GenericType, self).__init__(symbol)
- self.owner = owner
-
- def fits(self, target):
- report.info("\tGenericType.fits():: ignored, target = {}".format(target))
- return True
-
- class AutoType(Type):
- def __init__(self, candidates=None):
- super(AutoType, self).__init__(None)
- self.candidates = candidates
- def __str__(self):
- return "Auto:{}".format(self.candidates)
- class NameType(Type):
- def __init__(self, loc, name, typeArgs=[], left=None):
- super(NameType, self).__init__(None)
- self.loc = loc
- self.name = name
- self.typeArgs = typeArgs
- self.left = left
-
- def __str__(self):
- text = ""
- if self.left:
- text = str(self.left) + '.'
- text += self.name
- return text
- class RangeType(Type):
- def __init__(self):
- super(RangeType, self).__init__(None)
- class VoidType(StructInstType):
- def __init__(self):
- super(type(self), self).__init__(None)
- self.name = "Void"
- def fits(self, target):
- """ Other type cannot fit VoidType """
- return False
- class MappedArgType(Type):
- def __init__(self, symbol, typeArgs):
- assert len(typeArgs) == 2, "len(typeArgs) must be 2 (typeArgs=={0})".format(repr(typeArgs))
- super(type(self), self).__init__(symbol, typeArgs)
-
- def __str__(self):
- return "{0} => {1}".format(*self.typeArgs)
-
- class ComprehensionType(Type):
- def __init__(self, typeArg):
- super(ComprehensionType, self).__init__(None, [typeArg])
-