PlaceHolder all the things
This commit is contained in:
parent
a0645d94dd
commit
13f3f33740
@ -16,7 +16,8 @@ from .typing import (
|
||||
TypeVar,
|
||||
)
|
||||
|
||||
from .type3.types import Type3
|
||||
from .type3 import types as type3types
|
||||
from .type3.types import Type3, Type3OrPlaceholder, PlaceholderForType
|
||||
|
||||
class Expression:
|
||||
"""
|
||||
@ -24,12 +25,12 @@ class Expression:
|
||||
"""
|
||||
__slots__ = ('type3', 'type_var', )
|
||||
|
||||
type3: Optional[Type3]
|
||||
type3: Type3OrPlaceholder
|
||||
|
||||
type_var: Optional[TypeVar]
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.type3 = None
|
||||
self.type3 = PlaceholderForType([self])
|
||||
self.type_var = None
|
||||
|
||||
class Constant(Expression):
|
||||
@ -209,15 +210,17 @@ class FunctionParam:
|
||||
"""
|
||||
A parameter for a Function
|
||||
"""
|
||||
__slots__ = ('name', 'type_str', 'type_var', )
|
||||
__slots__ = ('name', 'type3', 'type_str', 'type_var', )
|
||||
|
||||
name: str
|
||||
type3: Type3
|
||||
type_str: str
|
||||
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.type_str = type_str
|
||||
self.type3 = type3
|
||||
self.type_str = type3.name
|
||||
self.type_var = None
|
||||
|
||||
class Function:
|
||||
@ -231,7 +234,7 @@ class Function:
|
||||
exported: bool
|
||||
imported: bool
|
||||
statements: List[Statement]
|
||||
returns_type3: Optional[Type3]
|
||||
returns_type3: Type3
|
||||
returns_str: str
|
||||
returns_type_var: Optional[TypeVar]
|
||||
posonlyargs: List[FunctionParam]
|
||||
@ -242,6 +245,7 @@ class Function:
|
||||
self.exported = False
|
||||
self.imported = False
|
||||
self.statements = []
|
||||
self.returns_type3 = type3types.none
|
||||
self.returns_str = 'None'
|
||||
self.returns_type_var = None
|
||||
self.posonlyargs = []
|
||||
|
||||
@ -131,7 +131,7 @@ class OurVisitor:
|
||||
|
||||
function.posonlyargs.append(FunctionParam(
|
||||
arg.arg,
|
||||
self.visit_type(module, arg.annotation).name,
|
||||
self.visit_type(module, arg.annotation),
|
||||
))
|
||||
|
||||
_not_implemented(not node.args.vararg, 'FunctionDef.args.vararg')
|
||||
|
||||
@ -13,6 +13,9 @@ class Error:
|
||||
def __init__(self, msg: str) -> None:
|
||||
self.msg = msg
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f'Error({repr(self.msg)})'
|
||||
|
||||
class RequireTypeSubstitutes:
|
||||
pass
|
||||
|
||||
@ -73,7 +76,7 @@ class SameTypeConstraint(ConstraintBase):
|
||||
if self.expected is self.actual:
|
||||
return None
|
||||
|
||||
raise NotImplementedError
|
||||
return Error(f'{self.expected:s} must be {self.actual:s} instead')
|
||||
|
||||
def get_new_placeholder_substitutes(self) -> SubstitutionMap:
|
||||
if isinstance(self.actual, types.PlaceholderForType):
|
||||
@ -84,7 +87,7 @@ class SameTypeConstraint(ConstraintBase):
|
||||
return {}
|
||||
|
||||
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 = smap[self.actual]
|
||||
|
||||
|
||||
@ -38,6 +38,10 @@ def expression(ctx: Context, inp: ourlang.Expression) -> Generator[ConstraintBas
|
||||
yield from constant(ctx, inp)
|
||||
return
|
||||
|
||||
if isinstance(inp, ourlang.VariableReference):
|
||||
yield SameTypeConstraint(inp.variable.type3, inp.type3)
|
||||
return
|
||||
|
||||
raise NotImplementedError(expression, inp)
|
||||
|
||||
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)
|
||||
|
||||
if inp.returns_type3 is None:
|
||||
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)
|
||||
yield SameTypeConstraint(inp.returns_type3, inp.statements[0].value.type3)
|
||||
|
||||
def module_constant_def(ctx: Context, inp: ourlang.ModuleConstantDef) -> Generator[ConstraintBase, None, None]:
|
||||
|
||||
yield from constant(ctx, inp.constant)
|
||||
|
||||
# FIXME: Redo this part
|
||||
|
||||
if (
|
||||
inp.type3 is types.u8
|
||||
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)
|
||||
|
||||
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():
|
||||
yield from module_constant_def(ctx, cdef)
|
||||
|
||||
|
||||
@ -33,6 +33,7 @@ def phasm_type3(inp: ourlang.Module) -> None:
|
||||
|
||||
if isinstance(check_result, Error):
|
||||
error_list.append(check_result)
|
||||
continue
|
||||
|
||||
if isinstance(check_result, RequireTypeSubstitutes):
|
||||
constraint_list.append(constraint)
|
||||
|
||||
@ -4,14 +4,14 @@ Contains the final types for use in Phasm
|
||||
These are actual, instantiated types; not the abstract types that the
|
||||
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):
|
||||
"""
|
||||
A protocol for classes that should be updated on substitution
|
||||
"""
|
||||
|
||||
type3: Optional['Type3']
|
||||
type3: 'Type3OrPlaceholder'
|
||||
"""
|
||||
The type to update
|
||||
"""
|
||||
@ -38,7 +38,7 @@ class Type3:
|
||||
|
||||
def __format__(self, format_spec: str) -> str:
|
||||
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)
|
||||
|
||||
@ -58,17 +58,11 @@ class PlaceholderForType:
|
||||
"""
|
||||
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]
|
||||
|
||||
NEXT_NUMBER: ClassVar[int] = 1
|
||||
|
||||
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]
|
||||
|
||||
def get_substituted(self, result_type: Type3) -> None:
|
||||
@ -85,10 +79,10 @@ class PlaceholderForType:
|
||||
def __repr__(self) -> str:
|
||||
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:
|
||||
return f'T{self.number}'
|
||||
return f'PhFT_{id(self)}'
|
||||
|
||||
def __format__(self, format_spec: str) -> str:
|
||||
if format_spec != 's':
|
||||
@ -97,8 +91,11 @@ class PlaceholderForType:
|
||||
return str(self)
|
||||
|
||||
def __eq__(self, other: Any) -> bool:
|
||||
if not isinstance(other, PlaceholderForType):
|
||||
raise NotImplementedError
|
||||
|
||||
return self is other
|
||||
|
||||
def __ne__(self, other: Any) -> bool:
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user