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() @dataclass class NebToken: pass @dataclass class NebLiteral(NebToken): type_: NebType value: T 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()