61 lines
1.6 KiB
Python
61 lines
1.6 KiB
Python
import re
|
|
from typing import Any
|
|
import lisp
|
|
import atom
|
|
|
|
|
|
class Reader:
|
|
tokens: list[str|Any]
|
|
|
|
def __init__(self):
|
|
self.tokens = []
|
|
self.interpreter = lisp.Lisp()
|
|
|
|
def run(self):
|
|
while self.peek() != "":
|
|
self.interpreter.evaluate(self.read_expression())
|
|
self.consume()
|
|
|
|
def tokenize(self, expression: str):
|
|
self.tokens += re.findall(r"""[\s,]*[;.*]*([()']|"(?:\\.|[^\\"])*"?|[^\s()'",;]*)""", expression)
|
|
|
|
def peek(self):
|
|
return self.tokens[0]
|
|
|
|
def consume(self):
|
|
token = self.tokens[0]
|
|
self.tokens = self.tokens[1:]
|
|
return token
|
|
|
|
def read_expression(self):
|
|
if len(self.tokens) == 0:
|
|
return None
|
|
if self.peek() == "(":
|
|
self.consume()
|
|
atomlist = []
|
|
token = self.peek()
|
|
while token != ")":
|
|
atomlist.append(self.read_expression())
|
|
while self.peek() == "":
|
|
self.consume()
|
|
expression: str = input("... ")
|
|
self.tokenize(expression)
|
|
token = self.peek()
|
|
self.consume()
|
|
return atomlist
|
|
else:
|
|
return self.read_atom()
|
|
|
|
def read_atom(self):
|
|
token = self.consume()
|
|
if token.upper() == "T":
|
|
return True
|
|
elif token.upper() == "NIL":
|
|
return False
|
|
try:
|
|
return int(token)
|
|
except ValueError:
|
|
try:
|
|
return float(token)
|
|
except ValueError:
|
|
return token |