from abc import ABC, abstractmethod from dataclasses import dataclass from typing import Callable, Dict, List as List_, Tuple as Tuple_ from ppp_ast import Statement from ppp_types import ArrayType, EnumType, FunctionType, ListType, StructType, TupleType, Type, Int as IntType, Str as StrType, Bool as BoolType, Void as VoidType, TypeType class Object(ABC): @abstractmethod def get_type(self) -> Type: ... @dataclass class Int(Object): num: int def get_type(self) -> Type: return IntType @dataclass class Str(Object): str: str def get_type(self) -> Type: return StrType @dataclass class Bool(Object): value: bool def get_type(self) -> Type: return BoolType @dataclass class Void_(Object): def get_type(self) -> Type: return VoidType Void = Void_() @dataclass class TypeObject(Object): type: Type def get_type(self) -> Type: return TypeType @dataclass class Tuple(Object): type: TupleType tuple: Tuple_[Object, ...] def get_type(self) -> Type: return self.type @dataclass class List(Object): type: ListType list: List_[Object] def get_type(self) -> Type: return self.type @dataclass class Array(Object): type: ArrayType array: List_[Object] def get_type(self) -> Type: return self.type @dataclass class Function(Object): type: FunctionType function: Tuple_[str, List_[Tuple_[str, Type]], Type, Statement, Callable[..., Object]] def get_type(self) -> Type: return self.type @dataclass class EnumValue(Object): type: EnumType name: str values: List_[Object] def get_type(self) -> Type: return self.type @dataclass class Struct(Object): type: StructType fields: Dict[str, Object] def get_type(self) -> Type: return self.type