Remove union types
I will need to implement polymorphism later to allow for functions like `len` to work. Len currently relies on saying that its argument is either a list or a string, as strings are not a subtype of lists.
This commit is contained in:
parent
dd3b933e03
commit
b02ca87760
@ -1,6 +1,6 @@
|
||||
from abc import ABC, abstractmethod
|
||||
from dataclasses import dataclass
|
||||
from typing import Dict, List, Optional, Tuple, Union
|
||||
from typing import Dict, List, Optional, Tuple
|
||||
|
||||
### Types ###
|
||||
|
||||
@ -15,13 +15,6 @@ class TupleTypeExpr(TypeExpression):
|
||||
def represent(self) -> str:
|
||||
assert False, ("Unimplemented")
|
||||
|
||||
@dataclass
|
||||
class UnionTypeExpr(TypeExpression):
|
||||
types: List[TypeExpression]
|
||||
|
||||
def represent(self) -> str:
|
||||
assert False, ("Unimplemented")
|
||||
|
||||
@dataclass
|
||||
class ListTypeExpr(TypeExpression):
|
||||
type: TypeExpression
|
||||
|
@ -1,5 +1,5 @@
|
||||
from dataclasses import dataclass
|
||||
from typing import Dict, List as List_, Optional, Tuple, Union
|
||||
from typing import Dict, List as List_, Optional, Tuple
|
||||
|
||||
from ppp_ast import *
|
||||
from ppp_lexer import Lexer
|
||||
@ -7,7 +7,7 @@ from ppp_object import Bool, EnumValue, Function, Int, Object, Str, Struct, Tupl
|
||||
from ppp_parser import is_valid_target, parse_statement
|
||||
from ppp_tokens import EofToken
|
||||
from ppp_stdlib import variables
|
||||
from ppp_types import EnumType, FunctionType, GenericType, Int as IntType, ListType, ReturnType, Str as StrType, StructType, TupleType, Type, TypeType, UnionType, VariableType, Void as VoidType
|
||||
from ppp_types import EnumType, FunctionType, GenericType, Int as IntType, ListType, ReturnType, Str as StrType, StructType, TupleType, Type, TypeType, VariableType, Void as VoidType
|
||||
|
||||
@dataclass
|
||||
class Declared:
|
||||
@ -31,7 +31,7 @@ class Constant:
|
||||
def from_obj(obj: Object) -> 'Declared':
|
||||
return Declared(obj.get_type(), obj)
|
||||
|
||||
VariableState = Union[Declared, Undeclared, Constant]
|
||||
VariableState = Declared | Undeclared | Constant
|
||||
|
||||
Module = Dict[str, VariableState]
|
||||
|
||||
@ -340,8 +340,6 @@ def calculate_type_expression(expression: TypeExpression, program: ProgramState,
|
||||
return ListType(calculate_type_expression(type_, program, must_resolve))
|
||||
case TupleTypeExpr(types_):
|
||||
return TupleType([calculate_type_expression(type, program, must_resolve) for type in types_])
|
||||
case UnionTypeExpr(types_):
|
||||
return UnionType([calculate_type_expression(type, program, must_resolve) for type in types_])
|
||||
case FunctionTypeExpr(arguments_, return_type_):
|
||||
return FunctionType([calculate_type_expression(argument, program, must_resolve) for argument in arguments_], calculate_type_expression(return_type_, program, must_resolve))
|
||||
case TypeSpecification(type_, types_):
|
||||
@ -413,7 +411,7 @@ class BreakResult:
|
||||
class NothingResult:
|
||||
pass
|
||||
|
||||
StatementsResult = Union[ReturnResult, ContinueResult, BreakResult, NothingResult]
|
||||
StatementsResult = ReturnResult | ContinueResult | BreakResult | NothingResult
|
||||
|
||||
def interpret_statements(statements: List_[Statement], program: ProgramState) -> StatementsResult:
|
||||
for statement in statements:
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
from abc import ABC, abstractmethod
|
||||
from dataclasses import dataclass
|
||||
from typing import Callable, Dict, List as List_, Tuple as Tuple_, Union as Union_
|
||||
from typing import Callable, Dict, List as List_, Tuple as Tuple_
|
||||
|
||||
from ppp_ast import Statement
|
||||
from ppp_types import ArrayType, EnumType, FunctionType, ListType, ReturnType, StructType, TupleType, Type, Int as IntType, Str as StrType, Bool as BoolType, Void as VoidType, TypeType
|
||||
|
@ -23,21 +23,10 @@ def parse_type_primary(lexer: Lexer) -> TypeExpression:
|
||||
if lexer.take_token(SymbolToken(Symbol.Open)):
|
||||
if lexer.take_token(SymbolToken(Symbol.Close)): return TupleTypeExpr([])
|
||||
|
||||
def parse_union(lexer: Lexer) -> TypeExpression:
|
||||
union_types: List[TypeExpression] = [parse_type(lexer)]
|
||||
while lexer.take_token(SymbolToken(Symbol.Pipe)):
|
||||
union_types.append(parse_type(lexer))
|
||||
if len(union_types) == 1:
|
||||
return union_types[0]
|
||||
return UnionTypeExpr(union_types)
|
||||
|
||||
types: List[TypeExpression] = [parse_union(lexer)]
|
||||
types: List[TypeExpression] = [parse_type(lexer)]
|
||||
while lexer.take_token(SymbolToken(Symbol.Comma)):
|
||||
types.append(parse_union(lexer))
|
||||
types.append(parse_type(lexer))
|
||||
lexer.assert_token(SymbolToken(Symbol.Close))
|
||||
if len(types) == 1 and isinstance(types[0], UnionTypeExpr):
|
||||
base_type = types[0]
|
||||
else:
|
||||
base_type = TupleTypeExpr(types)
|
||||
elif lexer.take_token(SymbolToken(Symbol.OpenSquare)):
|
||||
type = parse_type(lexer)
|
||||
|
@ -2,7 +2,7 @@ from typing import Callable, Dict, List, Tuple
|
||||
|
||||
from ppp_ast import Statements
|
||||
from ppp_object import Bool, EnumValue, Int, Object, Function, Str, TypeObject, Void, List as ListObject
|
||||
from ppp_types import Bool as BoolType, FunctionType, GenericType, Int as IntType, Str as StrType, Type, TypeType, VariableType, Void as VoidType, Object as ObjectType, UnionType, ListType
|
||||
from ppp_types import Bool as BoolType, FunctionType, GenericType, Int as IntType, Str as StrType, Type, TypeType, VariableType, Void as VoidType, Object as ObjectType, ListType
|
||||
|
||||
|
||||
def PythonFunction(name: str, parameters: List[Tuple[str, Type]], return_type: Type, func: Callable[..., Object]) -> Object:
|
||||
@ -41,7 +41,8 @@ def len_impl(list_: Object) -> Object:
|
||||
case _: assert False, ("Unimplemented", list_)
|
||||
assert False
|
||||
|
||||
Len = PythonFunction("len", [('list', UnionType([ListType(VariableType("")), StrType]))], IntType, len_impl)
|
||||
# TODO: Use polymorphism to make this work for both list<T> and str
|
||||
# Len = PythonFunction("len", [('list', UnionType([ListType(VariableType("")), StrType]))], IntType, len_impl)
|
||||
|
||||
def str_to_int_impl(str_: Object) -> Object:
|
||||
assert isinstance(str_, Str)
|
||||
@ -99,7 +100,7 @@ variables: Dict[str, Object] = {
|
||||
'void': VoidTypeObj,
|
||||
'debug_print': DebugPrint,
|
||||
'read': Read,
|
||||
'len': Len,
|
||||
# 'len': Len,
|
||||
'str_to_int': StrToInt,
|
||||
'none': NoneObj,
|
||||
'range': Range,
|
||||
|
@ -1,7 +1,5 @@
|
||||
from dataclasses import dataclass
|
||||
from enum import Enum
|
||||
from typing import List, Literal, Tuple, Union
|
||||
|
||||
|
||||
class Keyword(Enum):
|
||||
Enum = 'enum'
|
||||
@ -88,14 +86,7 @@ class SymbolToken:
|
||||
@dataclass
|
||||
class EofToken: pass
|
||||
|
||||
TokenContents = Union[
|
||||
KeywordToken,
|
||||
IdentifierToken,
|
||||
NumberToken,
|
||||
StringToken,
|
||||
SymbolToken,
|
||||
EofToken
|
||||
]
|
||||
TokenContents = KeywordToken | IdentifierToken | NumberToken | StringToken | SymbolToken | EofToken
|
||||
|
||||
@dataclass
|
||||
class Token:
|
||||
|
21
ppp_types.py
21
ppp_types.py
@ -1,7 +1,7 @@
|
||||
|
||||
from abc import ABC, abstractmethod
|
||||
from dataclasses import dataclass
|
||||
from typing import Dict, List, Tuple, Union
|
||||
from typing import Dict, List, Tuple
|
||||
|
||||
import sys
|
||||
sys.setrecursionlimit(1000)
|
||||
@ -40,10 +40,6 @@ class Type(ABC):
|
||||
case VariableType(self_name), VariableType(other_name):
|
||||
return self_name == other_name
|
||||
case _, VariableType(""): return True
|
||||
case type, UnionType(types):
|
||||
for union_type in types:
|
||||
if type.is_subtype_of(union_type): return True
|
||||
return False
|
||||
case BoolType(), BoolType(): return True
|
||||
case type, ObjectType(): return True
|
||||
case type_a, type_b if type_a.__class__ != type_b.__class__: return False
|
||||
@ -164,21 +160,6 @@ class FunctionType(Type):
|
||||
is_new_return_type, new_return_type = self.return_type.new_fill(types, stack+[id(self)])
|
||||
return (is_new_arguments or is_new_return_type, FunctionType(new_arguments, new_return_type))
|
||||
|
||||
@dataclass
|
||||
class UnionType(Type):
|
||||
types: List[Type]
|
||||
|
||||
def fill(self, types: Dict[str, Type], stack: List[int]) -> Type:
|
||||
if id(self) in stack: return self
|
||||
self.types = [type.fill(types, stack+[id(self)]) for type in self.types]
|
||||
return self
|
||||
|
||||
def new_fill(self, types: Dict[str, Type], stack: List[int]) -> Tuple[bool, Type]:
|
||||
is_new, new_types = self.new_fill_list(self.types, types, stack)
|
||||
return (is_new, UnionType(new_types))
|
||||
|
||||
def represent(self) -> str: return '('+'|'.join([type.represent() for type in self.types])+')'
|
||||
|
||||
class ObjectType(Primitive):
|
||||
def represent(self) -> str: return 'object'
|
||||
Object = ObjectType()
|
||||
|
Loading…
Reference in New Issue
Block a user