Had to implement both functions as arguments and type place holders (variables) for type constructors. Had to implement functions as a type as well. Still have to figure out how to pass functions around.
105 lines
3.5 KiB
Python
105 lines
3.5 KiB
Python
from typing import Dict, Iterable, List, Mapping, Optional
|
|
|
|
from .functions import (
|
|
Constraint_TypeClassInstanceExists,
|
|
ConstraintBase,
|
|
FunctionSignature,
|
|
TypeConstructorVariable,
|
|
TypeVariable,
|
|
TypeVariableContext,
|
|
)
|
|
from .types import Type3
|
|
|
|
|
|
class Type3ClassMethod:
|
|
__slots__ = ('name', 'signature', )
|
|
|
|
name: str
|
|
signature: FunctionSignature
|
|
|
|
def __init__(self, name: str, signature: FunctionSignature) -> None:
|
|
self.name = name
|
|
self.signature = signature
|
|
|
|
def __str__(self) -> str:
|
|
return f'{self.name} :: {self.signature}'
|
|
|
|
def __repr__(self) -> str:
|
|
return f'Type3ClassMethod({repr(self.name)}, {repr(self.signature)})'
|
|
|
|
Type3ClassArgs = tuple[TypeVariable] | tuple[TypeVariable, TypeVariable] | tuple[TypeConstructorVariable]
|
|
|
|
class Type3Class:
|
|
__slots__ = ('name', 'args', 'methods', 'operators', 'inherited_classes', )
|
|
|
|
name: str
|
|
args: Type3ClassArgs
|
|
methods: Dict[str, Type3ClassMethod]
|
|
operators: Dict[str, Type3ClassMethod]
|
|
inherited_classes: List['Type3Class']
|
|
|
|
def __init__(
|
|
self,
|
|
name: str,
|
|
args: Type3ClassArgs,
|
|
methods: Mapping[str, Iterable[Type3 | TypeVariable | list[Type3 | TypeVariable]]],
|
|
operators: Mapping[str, Iterable[Type3 | TypeVariable | list[Type3 | TypeVariable]]],
|
|
inherited_classes: Optional[List['Type3Class']] = None,
|
|
additional_context: Optional[Mapping[str, Iterable[ConstraintBase]]] = None,
|
|
) -> None:
|
|
self.name = name
|
|
self.args = args
|
|
|
|
self.methods = {
|
|
k: Type3ClassMethod(k, _create_signature(v, self))
|
|
for k, v in methods.items()
|
|
}
|
|
self.operators = {
|
|
k: Type3ClassMethod(k, _create_signature(v, self))
|
|
for k, v in operators.items()
|
|
}
|
|
self.inherited_classes = inherited_classes or []
|
|
|
|
if additional_context:
|
|
for func_name, constraint_list in additional_context.items():
|
|
func = self.methods.get(func_name) or self.operators.get(func_name)
|
|
assert func is not None # type hint
|
|
|
|
func.signature.context.constraints.extend(constraint_list)
|
|
|
|
def __repr__(self) -> str:
|
|
return self.name
|
|
|
|
def _create_signature(
|
|
method_arg_list: Iterable[Type3 | TypeVariable | list[Type3 | TypeVariable]],
|
|
type_class3: Type3Class,
|
|
) -> FunctionSignature:
|
|
context = TypeVariableContext()
|
|
if not isinstance(type_class3.args[0], TypeConstructorVariable):
|
|
context.constraints.append(Constraint_TypeClassInstanceExists(type_class3, type_class3.args))
|
|
|
|
signature_args: list[Type3 | TypeVariable | list[Type3 | TypeVariable]] = []
|
|
for method_arg in method_arg_list:
|
|
if isinstance(method_arg, Type3):
|
|
signature_args.append(method_arg)
|
|
continue
|
|
|
|
if isinstance(method_arg, list):
|
|
signature_args.append(method_arg)
|
|
continue
|
|
|
|
if isinstance(method_arg, TypeVariable):
|
|
type_constructor = method_arg.application.constructor
|
|
if type_constructor is None:
|
|
signature_args.append(method_arg)
|
|
continue
|
|
|
|
if (type_constructor, ) == type_class3.args:
|
|
context.constraints.append(Constraint_TypeClassInstanceExists(type_class3, [method_arg]))
|
|
signature_args.append(method_arg)
|
|
continue
|
|
|
|
raise NotImplementedError(method_arg)
|
|
|
|
return FunctionSignature(context, signature_args)
|