Skip to content

Instantly share code, notes, and snippets.

@BookOwl
Last active March 21, 2016 22:59
Show Gist options
  • Save BookOwl/78abe7e3138a0a45d8bb to your computer and use it in GitHub Desktop.
Save BookOwl/78abe7e3138a0a45d8bb to your computer and use it in GitHub Desktop.
A simple LISP interpreter for https://scratch.mit.edu/discuss/topic/189101/
import re
from operator import *
i=lambda p: p if type(p)!=tuple else{"cons":lambda a,b:(a,b),"car":lambda a:a[0],"cdr":lambda a:a[1],"cadr":lambda a:a[1][0],"+":add,"-":sub,"*":mul,"print":print}[p[0]](*map(i,p[1:]))
while 1:i(eval(re.sub("[\n ]+",",",re.sub("[a-z+\-*]+","'\g<0>'",input()).replace("'nil'","''"))or"''"))
import re
from functools import reduce
from operator import mul
# Dictionary of defined functions with lots of lambdas
FUNCTIONS = {"cons": lambda a, b: (a, b),
"car": lambda a: a[0],
"cdr": lambda a: a[1],
"cadr": lambda a: a[1][0],
"+": lambda *args: sum(args),
"-": lambda a, b: a - b,
"*": lambda *args: reduce(mul, args, 0),
"print": lambda arg: print(arg)}
def parse(prog):
"Parses a S-Expression by converting it into a tuple"
# Replace every symbol (but not numbers) with the symbol enclosed in '',
# so that when we run eval the symbols turn into strings
prog = re.sub("[a-zA-Z+\-*]+", "'\g<0>'", prog)
# Replace "nil" with None
prog = prog.replace("'nil'", "None")
# Replace all the newlines and spaces (Lisp list seperators)
# with ", " (Python tuple seperators)
prog = re.sub("[\n ]+", ", ", prog)
# prog is now valid tuple syntax, so run eval to turn it into one
return eval(prog)
def interpret(prog):
"Recursively interprets the parsed prog"
# If we are interpreting a literal (int or None), return it
if type(prog) in (int, type(None)):
return prog
# Else, we have a tuple
# Run the function given by the first item in the tuple
# with arguments given by recusivly interpreting the rest of the tuple
elif prog[0] in FUNCTIONS:
return FUNCTIONS[prog[0]](*tuple(map(interpret, prog[1:])))
def run(prog):
"A helper function that parses and inteprets prog"
return interpret(parse(prog))
if __name__ == "__main__":
print("OwlLISP REPL")
while True:
prog = input("Enter your program: ")
ret = run(prog)
if ret:
print(ret)
@BookOwl
Copy link
Author

BookOwl commented Mar 19, 2016

Next steps:

  • Add lambda
  • Add quoted lists

@jeandrek
Copy link

If you want to continue, I'd suggest to make it less code golf-y 📦 (not that you have to)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment