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): INT = auto() FLOAT = auto() STRING = auto() BOOL = auto() def __str__(self): return ":" + self.name.lower() @dataclass class NebToken: pass @dataclass class NebLiteral(NebToken): type_: NebType value: T 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(NebToken): pass class NebOpen(NebSeparator): pass class NebClose(NebSeparator): pass @dataclass class NebSymbol(NebToken): name: str @dataclass class NebExpression(NebToken): symbol: NebSymbol args: List[NebToken] 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) @dataclass class NebFunction(NebToken): name: str args: List[NebType] returns: NebType 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()