diff --git a/atom.py b/atom.py index 6f383ac..a53a990 100644 --- a/atom.py +++ b/atom.py @@ -1,2 +1,13 @@ class Atom: - pass \ No newline at end of file + car: Atom | int | str | bool | None + cdr: Atom | None + + def __init__(self, car: Atom|int|str|bool|None, cdr: Atom|None): + self.car = car + self.cdr = cdr + + def setval(self, atom: Atom | int | str | bool | None): + self.car = atom + + def append(self, atom: Atom): + self.cdr = atom \ No newline at end of file diff --git a/lisp.py b/lisp.py index 275f0a3..de5bcdb 100644 --- a/lisp.py +++ b/lisp.py @@ -1,5 +1,9 @@ import atom +import reader class Lisp: + def parse(self, expression): + return reader.tokenize(expression) + def evaluate(self, expression: str): - return expression.upper() \ No newline at end of file + return self.parse(expression) \ No newline at end of file diff --git a/reader.py b/reader.py new file mode 100644 index 0000000..67536fb --- /dev/null +++ b/reader.py @@ -0,0 +1,51 @@ +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 tokenize(self, expression: str): + self.tokens += re.findall(r"""[\s,]*[;.*]*([()']|"(?:\\.|[^\\"])*"?|[^\s()'",;]*)""", expression) + while self.peek() != "": + self.read_expression() + self.consume() + + 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) -> atom.Atom | None: + if len(self.tokens) == 0: + return None + if self.peek() == "(": + self.consume() + return self.read_list() + else: + return self.read_atom() + + def read_list(self): + token = self.peek() + last = atom.Atom(None, None) + first = last + while token != ")": + last.setval(self.read_expression()) + last.append(atom.Atom(None, None)) + last = last.cdr + token = self.peek() + self.consume() + return first + + def read_atom(self) -> atom.Atom: + print(self.peek()) + return atom.Atom(self.consume(), None) \ No newline at end of file diff --git a/repl.py b/repl.py index 0248b5c..92b1fe0 100644 --- a/repl.py +++ b/repl.py @@ -1,12 +1,12 @@ -import lisp +import reader def main(): print("Welcome message.") - state = lisp.Lisp() + interpreter = reader.Reader() # REPL Loop while True: expression: str = input("> ") - print(state.evaluate(expression)) + interpreter.tokenize(expression) if __name__ == "__main__": main() \ No newline at end of file