3
\$\begingroup\$

I'm building a very simple Lisp interpreter. Similar to the the one from here. Here is what I have so far for the parsing part, that is, everything from "text is passed to the the program" to "ast is built". How does the below look? What can be improved? The hardest part for me was the recursive read_from_tokens function.

import re
Symbol = str

def pops(L, d=None):
    "Pop from the left of the list, or return the default."
    return L.pop(0) if L else d

def parse(program):
    "Read a Scheme expression from a string and return tokens in AST."
    program = preprocess(program)
    assert program.count(')') == program.count('('), "Mismatched parens"
    return read_from_tokens(tokenize(program))

def preprocess(s):
    "Replace comments with a single space."
    return re.sub(r';.+', ' ', s)

def tokenize(s):
    "Convert a string into a list of tokens."
    return s.replace('(', ' ( ').replace(')', ' ) ').split()

def atom(token):
    "Return a number (only accepted literal) or a symbol."
    try:
        return int(token) if token.isdigit() else float(token)
    except ValueError:
        return Symbol(token)

def read_from_tokens(tokens):
    "Read one or more expression from a sequence of tokens. Returns a list of lists."
    L = []
    while (token := pops(tokens, ')')) != ')':
        L.append(atom(token) if token!='(' else read_from_tokens(tokens))
    return L

if __name__ == '__main__':
    print (parse("(define (+ 2 2) 10) (* pi (* r r))"))
    print (parse("(define r 10)"))
    print (parse("(* pi (* (+ 1 1) r))"))
\$\endgroup\$
3
  • \$\begingroup\$ No string literals? \$\endgroup\$ Commented Mar 31, 2021 at 5:24
  • \$\begingroup\$ @vnp nope, not yet. \$\endgroup\$ Commented Mar 31, 2021 at 7:34
  • 3
    \$\begingroup\$ A lot can be learned from Peter Norvig's Python examples, which usually combine elegance and practicality. If you want to pursue this topic, I recommend Ruslan Spivak's Let's build a simple interpreter. I have referred to them several times while working on an unusual parsing project over the past few months. \$\endgroup\$ Commented Mar 31, 2021 at 17:26

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.