Remove ppp_types0.py
It is just an old version of ppp_types.py, before I probably rewrote the way types worked.
This commit is contained in:
parent
9b960e3ecf
commit
659c79373d
180
ppp_types0.py
180
ppp_types0.py
@ -1,180 +0,0 @@
|
|||||||
from dataclasses import dataclass
|
|
||||||
from types import EllipsisType
|
|
||||||
from typing import Dict, Optional, Union as Union_, Tuple as Tuple_, List as List_
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class StructContents:
|
|
||||||
generics: 'List_[Type]'
|
|
||||||
members: 'Dict[str, Type]'
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class TupleContents:
|
|
||||||
elements: 'List_[Type]'
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class EnumContents:
|
|
||||||
generics: 'List_[Type]'
|
|
||||||
members: 'Dict[str, Union_[Dict[str, Type], List_[Type]]]'
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class UnknownContents:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class FunctionContents:
|
|
||||||
arguments: 'List_[Type]'
|
|
||||||
return_type: 'Type'
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class ListContents:
|
|
||||||
type: 'Optional[Type]'
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class UnionContents:
|
|
||||||
types: 'List_[Type]'
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class Type:
|
|
||||||
name: str
|
|
||||||
contents: Union_[EnumContents, StructContents, TupleContents, FunctionContents, ListContents, UnknownContents, UnionContents]
|
|
||||||
|
|
||||||
def specify(self, *types: 'Type') -> 'Type':
|
|
||||||
assert False, ("Unimplemented")
|
|
||||||
|
|
||||||
def is_subtype_of(self, other: 'Type') -> bool: # TODO: Maybe return any generics that match
|
|
||||||
if other.name == 'object': return True
|
|
||||||
match self.contents, other.contents:
|
|
||||||
case (EnumContents(self_members), EnumContents(other_members)) | (StructContents(self_members), StructContents(other_members)):
|
|
||||||
return self.name == other.name
|
|
||||||
case TupleContents(self_elements), TupleContents(other_elements):
|
|
||||||
if self.name != other.name: return False
|
|
||||||
if len(self_elements) != len(other_elements): return False
|
|
||||||
for (self_element, other_element) in zip(self_elements, other_elements):
|
|
||||||
if not self_element.is_subtype_of(other_element): return False
|
|
||||||
return True
|
|
||||||
case FunctionContents(self_arguments, self_return_type), FunctionContents(other_arguments, other_return_type):
|
|
||||||
for (self_argument, other_argument) in zip(self_arguments, other_arguments):
|
|
||||||
if not other_argument.is_subtype_of(self_argument): return False
|
|
||||||
return self_return_type.is_subtype_of(other_return_type)
|
|
||||||
case ListContents(self_type), ListContents(other_type):
|
|
||||||
if self_type is None: return True
|
|
||||||
if other_type is None: return True
|
|
||||||
return self_type.is_subtype_of(other_type)
|
|
||||||
case UnionContents(self_types), UnionContents(other_types):
|
|
||||||
for type_ in self_types:
|
|
||||||
if not type_.is_subtype_of(other): return False
|
|
||||||
return True
|
|
||||||
case a, b if type(a) == type(b):
|
|
||||||
assert False, ("Unimplemented", self, other)
|
|
||||||
case _, UnionContents(types):
|
|
||||||
for type_ in types:
|
|
||||||
if self.is_subtype_of(type_): return True
|
|
||||||
return False
|
|
||||||
case _, _:
|
|
||||||
return False
|
|
||||||
assert False, ("Unimplemented")
|
|
||||||
|
|
||||||
def fill(self, types: 'Dict[str, Type]') -> 'Type':
|
|
||||||
match self.contents:
|
|
||||||
case TupleContents(elements):
|
|
||||||
return Type(self.name, TupleContents([type.fill(types) for type in elements]))
|
|
||||||
case EnumContents(generics, members):
|
|
||||||
assert not generics # TODO
|
|
||||||
|
|
||||||
new_members: Dict[str, Union_[Dict[str, Type], List_[Type]]] = {}
|
|
||||||
for name in members:
|
|
||||||
member = members[name]
|
|
||||||
if isinstance(member, list):
|
|
||||||
new_members[name] = [type.fill(types) for type in member]
|
|
||||||
elif isinstance(member, dict):
|
|
||||||
new_members[name] = {field: member[field].fill(types) for field in member}
|
|
||||||
else:
|
|
||||||
assert False, "Unreachable"
|
|
||||||
|
|
||||||
return Type(self.name, EnumContents(generics, new_members))
|
|
||||||
case StructContents(generics, members):
|
|
||||||
assert not generics # TODO
|
|
||||||
return Type(self.name, StructContents(generics, {field: members[field].fill(types) for field in members}))
|
|
||||||
case ListContents(type):
|
|
||||||
return Type(self.name, ListContents(type.fill(types) if type else None))
|
|
||||||
case UnknownContents():
|
|
||||||
return types[self.name] if self.name in types else self
|
|
||||||
case UnionContents(types_):
|
|
||||||
return Type(self.name, UnionContents([type.fill(types) for type in types_]))
|
|
||||||
case FunctionContents(arguments, return_type):
|
|
||||||
return Type(self.name, FunctionContents([argument.fill(types) for argument in arguments], return_type.fill(types)))
|
|
||||||
case _:
|
|
||||||
assert False, ("Unimplemented", self.contents)
|
|
||||||
assert False, "Unreachable"
|
|
||||||
|
|
||||||
def represent(self) -> str:
|
|
||||||
match self.contents:
|
|
||||||
case EnumContents(generics, _) | StructContents(generics, _): return self.name + ("<"+', '.join([generic.represent() for generic in generics])+">" if generics else '')
|
|
||||||
case TupleContents(elements): return (self.name if self.name != "tuple" else '') + ('('+', '.join([generic.represent() for generic in elements])+')' if elements else '')
|
|
||||||
case ListContents(type): return (type.represent() if type else '')+'[]'
|
|
||||||
case UnknownContents(): return self.name+"?"
|
|
||||||
case UnionContents(types): return '('+'|'.join([type.represent() for type in types])+')'
|
|
||||||
case FunctionContents(arguments, return_type): return "("+', '.join([type.represent() for type in arguments])+") -> "+return_type.represent()
|
|
||||||
assert False, ("Unimplemented")
|
|
||||||
|
|
||||||
def __eq__(self, other) -> bool:
|
|
||||||
return isinstance(other, Type) and self.is_subtype_of(other) and other.is_subtype_of(self)
|
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
|
||||||
try:
|
|
||||||
return self.represent()
|
|
||||||
except AssertionError:
|
|
||||||
return f"Unimplemented {self.contents.__class__.__name__}"
|
|
||||||
|
|
||||||
def primitive(name: str) -> Type: return Type(name, TupleContents([]))
|
|
||||||
Int = primitive("int")
|
|
||||||
Str = primitive("str")
|
|
||||||
Bool = primitive("bool")
|
|
||||||
Void = primitive("void")
|
|
||||||
TypeType = primitive("type")
|
|
||||||
|
|
||||||
def Tuple(*types: Type) -> Type: return Type("tuple", TupleContents(list(types)))
|
|
||||||
def List(type: Optional[Type]=None) -> Type: return Type("list", ListContents(type))
|
|
||||||
|
|
||||||
def Function(*arguments_and_return_type: Type) -> Type:
|
|
||||||
assert arguments_and_return_type, "Must have a return value"
|
|
||||||
return Type("function", FunctionContents(list(arguments_and_return_type[:-1]), arguments_and_return_type[-1]))
|
|
||||||
|
|
||||||
Unit = Tuple()
|
|
||||||
|
|
||||||
def Union(*types: Type) -> Type: return Type("union", UnionContents(list(types)))
|
|
||||||
def Return(type: Type) -> Type:
|
|
||||||
return Type('return', StructContents([type], {'value': type}))
|
|
||||||
|
|
||||||
Object = primitive('object')
|
|
||||||
|
|
||||||
# TODO: struct enum members
|
|
||||||
def EnumMember(enum_type: Type, *types: Type) -> Type: return Type('enum_tuple_member', FunctionContents(list(types), enum_type))
|
|
||||||
|
|
||||||
# def issubclassof(type1: Type, type2: Type) -> bool:
|
|
||||||
# if type1.name != 'union' and type2.name == 'union':
|
|
||||||
# return type1 in type2.generics
|
|
||||||
# if type1.name != type2.name: return False
|
|
||||||
# if not type2.generics: return True
|
|
||||||
# if len(type1.generics) != len(type2.generics): return False
|
|
||||||
# if type1.name == '->':
|
|
||||||
# for (type_a, type_b) in zip(type1.generics[:-1], type2.generics[:-1]):
|
|
||||||
# if not issubclassof(type_b, type_a): return False
|
|
||||||
# return issubclassof(type1.generics[-1], type2.generics[-1])
|
|
||||||
# if type1.name == 'union': assert False, ("Unimplemented", type1, type2)
|
|
||||||
# if type1.name == 'tuple': return all([issubclassof(type_a, type_b) for (type_a, type_b) in zip(type1.generics, type2.generics)])
|
|
||||||
# assert False, ("Unimplemented", type1, type2)
|
|
||||||
|
|
||||||
# Void = Type('void', TupleContents([]))
|
|
||||||
# AbstractFunction = Type('->', [])
|
|
||||||
# def Function(*arguments_and_return_type: Type) -> Type:
|
|
||||||
# assert arguments_and_return_type, "Must have a return value"
|
|
||||||
# return AbstractFunction.specify(*arguments_and_return_type)
|
|
||||||
|
|
||||||
# Int = Type('int', [], False)
|
|
||||||
# String = Type('str', [], False)
|
|
||||||
# Bool = Type('bool', [], False)
|
|
||||||
# def List(type: Type) -> Type: return Type('list', [type])
|
|
||||||
|
|
||||||
# Unit = Type('unit', [], False)
|
|
||||||
# def Tuple(*types: Type) -> Type: return Type('tuple', list(types)) if types else Unit
|
|
Loading…
Reference in New Issue
Block a user