Now both dynamic and static arrays can be fully fold'ed. Also adds support for type classes that have a function argument. Also, various usability improvements to WasmGenerator. Also, integration tests now don't dump their stuff without VERBOSE=1, this speeds up the tests suite by a factor of 9. Also, tests can now set with_traces to add a number of tracing functions for help debugging your code.
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)
|