PlaceHolder all the things
This commit is contained in:
parent
a0645d94dd
commit
13f3f33740
@ -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 = []
|
||||||
|
|||||||
@ -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')
|
||||||
|
|||||||
@ -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]
|
||||||
|
|
||||||
|
|||||||
@ -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)
|
||||||
|
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
@ -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,8 +91,11 @@ class PlaceholderForType:
|
|||||||
return str(self)
|
return str(self)
|
||||||
|
|
||||||
def __eq__(self, other: Any) -> bool:
|
def __eq__(self, other: Any) -> bool:
|
||||||
|
if not isinstance(other, PlaceholderForType):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
return self is other
|
||||||
|
|
||||||
def __ne__(self, other: Any) -> bool:
|
def __ne__(self, other: Any) -> bool:
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user