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): pass class NebClose(NebSeparator): pass class NebSymbol(NebToken): def __init__(self, name): super().__init__(NebType.SYMBOL) self.name = name class NebExpression(NebToken): def __init__(self, symbol, args): super().__init__(NebType.EXPR) self.symbol = symbol self.args = args def maybe_sig(self): out = [] for arg in self.args: if isinstance(arg, NebLiteral): out.append(":" + arg.type_.name.lower()) else: raise Exception("expressions must have a list of literals") #TODO not true return " ".join(out) 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()