experiment with methods of parametric type

pull/14/head
pca006132 2020-12-24 11:16:36 +08:00 committed by pca006132
parent a46edc8a47
commit 3457e594ec
4 changed files with 28 additions and 5 deletions

View File

@ -13,6 +13,9 @@ class Vec:
else:
return Vec([self.v[i] + other.v[i] for i in range(len(self.v))])
def get(self, index: int32) -> int32:
return self.v.head()
T = TypeVar('T', int32, list[int32])

View File

@ -88,8 +88,10 @@ def resolve_call(obj,
# TODO: we may want to return the substitution, for monomorphization...
f_args = None
f_result = None
subst = {}
if obj is not None:
obj = obj.subst(assumptions)
subst = obj.get_subst()
if obj is None:
if fn in ctx.functions:
f = ctx.functions[fn]
@ -107,7 +109,8 @@ def resolve_call(obj,
f_args, f_result = TupleType([]), c
else:
raise CustomError(f"No such function {fn}")
elif isinstance(obj, PrimitiveType) or isinstance(obj, ClassType):
elif isinstance(obj, PrimitiveType) or isinstance(obj, ClassType) \
or isinstance(obj, ParametricType):
if fn in obj.methods:
f = obj.methods[fn]
if len(f[0]) == 0 or (not isinstance(f[0][0], SelfType) and \
@ -154,7 +157,7 @@ def resolve_call(obj,
raise CustomError("Divergent type after constraints substitution")
a = TupleType(args)
subst = find_subst(assumptions, {}, a, f_args)
subst = find_subst(assumptions, subst, a, f_args)
if isinstance(subst, str):
raise CustomError(f"type check failed: {subst}")
result = f_result.subst(subst)

View File

@ -66,6 +66,11 @@ i32.methods['__init__'] = ([SelfType(), I], None, {'I'})
i64.methods['__init__'] = ([SelfType(), I], None, {'I'})
f32.methods['__init__'] = ([SelfType(), I], None, {'I'})
ParametricType.method_table['list'] = {
'get': ([SelfType(), i32], TypeVariable('T1', []), set()),
'head': ([SelfType()], TypeVariable('T1', []), set())
}
simplest_ctx = Context({}, types)
simplest_ctx.functions['len'] = ([ListType(A)], i32, {'A'})
simplest_ctx.functions['range'] = ([i32], ListType(i32), set())

View File

@ -23,6 +23,9 @@ class Type:
return tv
return self
def get_subst(self):
return {}
class BotType:
def __eq__(self, other):
@ -113,10 +116,16 @@ class VirtualClassType(Type):
class ParametricType(Type):
params: list[Type]
name: str
def __init__(self, params: list[Type]):
method_table = {}
def __init__(self, name, params: list[Type]):
super().__init__()
self.params = params
self.name = name
if name in ParametricType.method_table:
self.methods = ParametricType.method_table[name]
def __eq__(self, other):
if type(self) != type(other) or len(self.params) != len(other.params):
@ -148,9 +157,12 @@ class ParametricType(Type):
s.params = [v.inv_subst(subst) for v in self.params]
return s
def get_subst(self):
return {f'T{i + 1}': v for i, v in enumerate(self.params)}
class ListType(ParametricType):
def __init__(self, param: Type):
super().__init__([param])
super().__init__('list', [param])
def __str__(self):
return f"list[{self.params[0]}]"
@ -158,7 +170,7 @@ class ListType(ParametricType):
class TupleType(ParametricType):
def __init__(self, params: list[Type]):
super().__init__(params)
super().__init__('tuple', params)
def __str__(self):
return f"tuple[{', '.join([str(v) for v in self.params])}]"