from dataclasses import dataclass from enum import Enum, auto from typing import TypeVar, List T = TypeVar("T", int, float, str, bool) # classes class NebType(Enum): ANY = auto() INT = auto() FLOAT = auto() NUMBER = auto() STRING = auto() BOOL = auto() EXPR = auto() SYMBOL = auto() def __str__(self): return self.name.lower() class NebBaseType: def __init__(self, type_name, type_): self.type_name = type_name self.type_ = type_ def __str__(self): return f":{self.type_name}" class NebAny(NebBaseType): pass class NebLiteral(NebAny): def __init__(self, type_name, type_, value): super().__init__(type_name, type_) self.value = value def __str__(self): fixed = str(self.value) #if self.type_ == NebBaseType.BOOL: if isinstance(self, NebBool): fixed = f"#{str(self.value).lower()}" #elif self.type_ == NebBaseType.STRING: elif isinstance(self, NebString): fixed = f'"{self.value}"' return f"{fixed} <:{self.type_name}>" class NebSeparator(): pass class NebOpen(NebSeparator): def __str__(self): return "(" class NebClose(NebSeparator): def __str__(self): return ")" class NebSymbol(NebBaseType): def __init__(self, name): super().__init__("symbol", NebType.SYMBOL) self.name = name def __str__(self): return f"'{self.name}" class NebExpression(NebBaseType): def __init__(self, symbol, args): super().__init__("expr", NebType.EXPR) self.symbol = symbol self.args = args self.returns = None def set_returns(self, returns): self.returns = returns def __str__(self): out = f"({self.symbol}" for arg in self.args: out += f" {arg}" out += f") <:{self.type_}> -> <{self.out_sig()}>" return out def in_sig(self): return " ".join(f":{arg.type_.name.lower()}" for arg in self.args) def out_sig(self): if self.returns is None: return "?" else: return ":" + self.returns.lower() class NebFunction(): def __init__(self, name, args, returns): self.name = name self.args = args self.returns = returns class NebBool(NebLiteral): def __init__(self, value): super().__init__("bool", NebType.BOOL, value) class NebString(NebLiteral): def __init__(self, value): super().__init__("string", NebType.STRING, value) class NebNumber(NebLiteral): pass class NebInt(NebNumber): def __init__(self, value): super().__init__("int", NebType.INT, value) class NebFloat(NebNumber): def __init__(self, value): super().__init__("float", NebType.FLOAT, value)