Files
lisp-interpreter/reader.py
T
2026-04-26 20:57:29 -06:00

62 lines
1.7 KiB
Python

import re
import lisp
class Reader:
tokens: list[str]
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
elif self.peek() == "'":
# Expand the quote macro!
self.consume()
return ["quote", self.read_expression()]
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