def parser(token): if token == '': return Atom('') if type(token) == list: if len(token) == 0: raise Exception("empty compounds not allowed") return Compound([parser(x) for x in token]) if type(token) == str: if len(token) >= 2 and token[0] == '"' and token[-1] == '"': return String(token[1:-1]) if token == '#f': return Boolean(False) if token == '#t': return Boolean(True) num = maybe_number(token) if num is not None: return Number(num) if is_identifier(token): return Identifier(token) raise Exception(f"invalid token: {token}")
def parser(token): if token == '': return Atom('') if type(token) == list: ## What about empty compounds, are they allowed by the grammar? return Compound([parser(x) for x in token]) if type(token) == str: if len(token) >= 2 and token[0] == '"' and token[-1] == '"': return String(token[1:-1]) if token == '#f': return Boolean(False) if token == '#t': return Boolean(True) num = maybe_number(token) if num is not None: return Number(num) if is_identifier(token): return Identifier(token) ## Actually nice error messages raise Exception(f"invalid token: {token}")
def make_message(channel, timestamp, nickname, text): # (message "{channel}" {unix timestamp} "{nickname}" "{text}") root = Compound([ Identifier("message"), String(channel), Number(int(timestamp)), String(nickname), String(text), ]) return str(root) + '\n'
def __str__(self): exp = Compound([ Identifier("error"), String(self.message), ]) return str(exp)
def __str__(self): exp = Compound([ Identifier("matrix"), *self.values, ]) return str(exp)
def __str__(self): exp = Compound([ Identifier("vector"), *[Number(v) for v in self.values] ]) return str(exp)
def make_error(text): # (error "{text}") root = Compound([Identifier("error"), String(text)]) return str(root) + '\n'
def make_ok(): # (ok) root = Compound([Identifier("ok")]) return str(root) + '\n'