PlaceHolder all the things

This commit is contained in:
Johan B.W. de Vries 2022-11-17 15:23:56 +01:00
parent a0645d94dd
commit 13f3f33740
6 changed files with 35 additions and 39 deletions

View File

@ -16,7 +16,8 @@ from .typing import (
TypeVar, TypeVar,
) )
from .type3.types import Type3 from .type3 import types as type3types
from .type3.types import Type3, Type3OrPlaceholder, PlaceholderForType
class Expression: class Expression:
""" """
@ -24,12 +25,12 @@ class Expression:
""" """
__slots__ = ('type3', 'type_var', ) __slots__ = ('type3', 'type_var', )
type3: Optional[Type3] type3: Type3OrPlaceholder
type_var: Optional[TypeVar] type_var: Optional[TypeVar]
def __init__(self) -> None: def __init__(self) -> None:
self.type3 = None self.type3 = PlaceholderForType([self])
self.type_var = None self.type_var = None
class Constant(Expression): class Constant(Expression):
@ -209,15 +210,17 @@ class FunctionParam:
""" """
A parameter for a Function A parameter for a Function
""" """
__slots__ = ('name', 'type_str', 'type_var', ) __slots__ = ('name', 'type3', 'type_str', 'type_var', )
name: str name: str
type3: Type3
type_str: str type_str: str
type_var: Optional[TypeVar] type_var: Optional[TypeVar]
def __init__(self, name: str, type_str: str) -> None: def __init__(self, name: str, type3: Type3) -> None:
self.name = name self.name = name
self.type_str = type_str self.type3 = type3
self.type_str = type3.name
self.type_var = None self.type_var = None
class Function: class Function:
@ -231,7 +234,7 @@ class Function:
exported: bool exported: bool
imported: bool imported: bool
statements: List[Statement] statements: List[Statement]
returns_type3: Optional[Type3] returns_type3: Type3
returns_str: str returns_str: str
returns_type_var: Optional[TypeVar] returns_type_var: Optional[TypeVar]
posonlyargs: List[FunctionParam] posonlyargs: List[FunctionParam]
@ -242,6 +245,7 @@ class Function:
self.exported = False self.exported = False
self.imported = False self.imported = False
self.statements = [] self.statements = []
self.returns_type3 = type3types.none
self.returns_str = 'None' self.returns_str = 'None'
self.returns_type_var = None self.returns_type_var = None
self.posonlyargs = [] self.posonlyargs = []

View File

@ -131,7 +131,7 @@ class OurVisitor:
function.posonlyargs.append(FunctionParam( function.posonlyargs.append(FunctionParam(
arg.arg, arg.arg,
self.visit_type(module, arg.annotation).name, self.visit_type(module, arg.annotation),
)) ))
_not_implemented(not node.args.vararg, 'FunctionDef.args.vararg') _not_implemented(not node.args.vararg, 'FunctionDef.args.vararg')

View File

@ -13,6 +13,9 @@ class Error:
def __init__(self, msg: str) -> None: def __init__(self, msg: str) -> None:
self.msg = msg self.msg = msg
def __repr__(self) -> str:
return f'Error({repr(self.msg)})'
class RequireTypeSubstitutes: class RequireTypeSubstitutes:
pass pass
@ -73,7 +76,7 @@ class SameTypeConstraint(ConstraintBase):
if self.expected is self.actual: if self.expected is self.actual:
return None return None
raise NotImplementedError return Error(f'{self.expected:s} must be {self.actual:s} instead')
def get_new_placeholder_substitutes(self) -> SubstitutionMap: def get_new_placeholder_substitutes(self) -> SubstitutionMap:
if isinstance(self.actual, types.PlaceholderForType): if isinstance(self.actual, types.PlaceholderForType):
@ -84,7 +87,7 @@ class SameTypeConstraint(ConstraintBase):
return {} return {}
def substitute_placeholders(self, smap: SubstitutionMap) -> None: def substitute_placeholders(self, smap: SubstitutionMap) -> None:
if isinstance(self.actual, types.PlaceholderForType) and self.actual in smap: if isinstance(self.actual, types.PlaceholderForType) and self.actual in smap: # FIXME: Check recursive?
self.actual.get_substituted(smap[self.actual]) self.actual.get_substituted(smap[self.actual])
self.actual = smap[self.actual] self.actual = smap[self.actual]

View File

@ -38,6 +38,10 @@ def expression(ctx: Context, inp: ourlang.Expression) -> Generator[ConstraintBas
yield from constant(ctx, inp) yield from constant(ctx, inp)
return return
if isinstance(inp, ourlang.VariableReference):
yield SameTypeConstraint(inp.variable.type3, inp.type3)
return
raise NotImplementedError(expression, inp) raise NotImplementedError(expression, inp)
def function(ctx: Context, inp: ourlang.Function) -> Generator[ConstraintBase, None, None]: def function(ctx: Context, inp: ourlang.Function) -> Generator[ConstraintBase, None, None]:
@ -46,22 +50,14 @@ def function(ctx: Context, inp: ourlang.Function) -> Generator[ConstraintBase, N
yield from expression(ctx, inp.statements[0].value) yield from expression(ctx, inp.statements[0].value)
if inp.returns_type3 is None: yield SameTypeConstraint(inp.returns_type3, inp.statements[0].value.type3)
raise NotImplementedError
actual: types.Type3OrPlaceholder
if inp.statements[0].value.type3 is None:
print('inp.statements[0].value', inp.statements[0].value)
actual = types.PlaceholderForType([inp.statements[0].value])
else:
actual = inp.statements[0].value.type3
yield SameTypeConstraint(inp.returns_type3, actual)
def module_constant_def(ctx: Context, inp: ourlang.ModuleConstantDef) -> Generator[ConstraintBase, None, None]: def module_constant_def(ctx: Context, inp: ourlang.ModuleConstantDef) -> Generator[ConstraintBase, None, None]:
yield from constant(ctx, inp.constant) yield from constant(ctx, inp.constant)
# FIXME: Redo this part
if ( if (
inp.type3 is types.u8 inp.type3 is types.u8
or inp.type3 is types.u32 or inp.type3 is types.u32
@ -86,11 +82,6 @@ def module_constant_def(ctx: Context, inp: ourlang.ModuleConstantDef) -> Generat
raise NotImplementedError(constant, inp, inp.type3) raise NotImplementedError(constant, inp, inp.type3)
def module(ctx: Context, inp: ourlang.Module) -> Generator[ConstraintBase, None, None]: def module(ctx: Context, inp: ourlang.Module) -> Generator[ConstraintBase, None, None]:
for func in inp.functions.values():
assert func.returns_type3 is not None, 'TODO'
for param in func.posonlyargs:
assert False, 'TODO'
for cdef in inp.constant_defs.values(): for cdef in inp.constant_defs.values():
yield from module_constant_def(ctx, cdef) yield from module_constant_def(ctx, cdef)

View File

@ -33,6 +33,7 @@ def phasm_type3(inp: ourlang.Module) -> None:
if isinstance(check_result, Error): if isinstance(check_result, Error):
error_list.append(check_result) error_list.append(check_result)
continue
if isinstance(check_result, RequireTypeSubstitutes): if isinstance(check_result, RequireTypeSubstitutes):
constraint_list.append(constraint) constraint_list.append(constraint)

View File

@ -4,14 +4,14 @@ Contains the final types for use in Phasm
These are actual, instantiated types; not the abstract types that the These are actual, instantiated types; not the abstract types that the
constraint generator works with. constraint generator works with.
""" """
from typing import Any, ClassVar, Dict, Iterable, Optional, List, Protocol, Union from typing import Any, Dict, Iterable, List, Protocol, Union
class ExpressionProtocol(Protocol): class ExpressionProtocol(Protocol):
""" """
A protocol for classes that should be updated on substitution A protocol for classes that should be updated on substitution
""" """
type3: Optional['Type3'] type3: 'Type3OrPlaceholder'
""" """
The type to update The type to update
""" """
@ -38,7 +38,7 @@ class Type3:
def __format__(self, format_spec: str) -> str: def __format__(self, format_spec: str) -> str:
if format_spec != 's': if format_spec != 's':
raise TypeError('unsupported format string passed to Type3.__format__') raise TypeError(f'unsupported format string passed to Type3.__format__: {format_spec}')
return str(self) return str(self)
@ -58,17 +58,11 @@ class PlaceholderForType:
""" """
A placeholder type, for when we don't know the final type yet A placeholder type, for when we don't know the final type yet
""" """
__slots__ = ('number', 'update_on_substitution', ) __slots__ = ('update_on_substitution', )
number: int
update_on_substitution: List[ExpressionProtocol] update_on_substitution: List[ExpressionProtocol]
NEXT_NUMBER: ClassVar[int] = 1
def __init__(self, update_on_substitution: Iterable[ExpressionProtocol]) -> None: def __init__(self, update_on_substitution: Iterable[ExpressionProtocol]) -> None:
self.number = PlaceholderForType.NEXT_NUMBER
PlaceholderForType.NEXT_NUMBER += 1
self.update_on_substitution = [*update_on_substitution] self.update_on_substitution = [*update_on_substitution]
def get_substituted(self, result_type: Type3) -> None: def get_substituted(self, result_type: Type3) -> None:
@ -85,10 +79,10 @@ class PlaceholderForType:
def __repr__(self) -> str: def __repr__(self) -> str:
uos = ', '.join(repr(x) for x in self.update_on_substitution) uos = ', '.join(repr(x) for x in self.update_on_substitution)
return f'PlaceholderForType({self.number} [{uos}])' return f'PlaceholderForType({id(self)}, [{uos}])'
def __str__(self) -> str: def __str__(self) -> str:
return f'T{self.number}' return f'PhFT_{id(self)}'
def __format__(self, format_spec: str) -> str: def __format__(self, format_spec: str) -> str:
if format_spec != 's': if format_spec != 's':
@ -97,7 +91,10 @@ class PlaceholderForType:
return str(self) return str(self)
def __eq__(self, other: Any) -> bool: def __eq__(self, other: Any) -> bool:
raise NotImplementedError if not isinstance(other, PlaceholderForType):
raise NotImplementedError
return self is other
def __ne__(self, other: Any) -> bool: def __ne__(self, other: Any) -> bool:
raise NotImplementedError raise NotImplementedError