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() @dataclass class NebToken: type_: NebType class NebLiteral(NebToken): def __init__(self, type_, value): super().__init__(type_) self.value = value def __str__(self): fixed = str(self.value) if self.type_ == NebType.BOOL: fixed = f"#{str(self.value).lower()}" elif self.type_ == NebType.STRING: fixed = f'"{self.value}"' return f"{fixed} <{self.type_}>" class NebSeparator(): pass class NebOpen(NebSeparator): def __str__(self): return "(" class NebClose(NebSeparator): def __str__(self): return ")" class NebSymbol(NebToken): def __init__(self, name): super().__init__(NebType.SYMBOL) self.name = name def __str__(self): return f"'{self.name}" class NebExpression(NebToken): def __init__(self, symbol, args): super().__init__(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() def sig(self): return (self.in_sig() + " > " + self.out_sig()).strip() class NebFunction(): def __init__(self, name, args, returns): self.name = name self.args = args self.returns = returns def in_sig(self): return " ".join(":" + x.name.lower() for x in self.args) def out_sig(self): return ":" + self.returns.lower() def sig(self): return (self.in_sig() + " > " + self.out_sig()).strip()