Created
December 10, 2014 00:57
-
-
Save SamuraiT/08c11293f4ff7f7fc369 to your computer and use it in GitHub Desktop.
simple lisp interpreter
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# coding: utf-8 | |
Env = dict | |
Symbol = str | |
List = list | |
Number = (int, float) | |
def tokenize(chars): | |
return chars.replace('(', ' ( ').replace(')', ' ) ').split() | |
def parse(program): | |
return read_from_tokens(tokenize(program)) | |
def read_from_tokens(tokens): | |
if len(tokens) == 0: raise SyntaxError("unexpected EOF while reading") | |
token = tokens.pop(0) | |
if token == '(': | |
L = [] | |
while tokens[0] != ')': | |
L.append(read_from_tokens(tokens)) | |
#print(L) | |
tokens.pop(0) # pop off ')' | |
return L | |
elif token == ')': raise SyntaxError('unexpected') | |
else: return atom(token) | |
def atom(token): | |
try: return int(token) | |
except ValueError: | |
try: return float(token) | |
except ValueError: | |
return Symbol(token) | |
def starndard_env(): | |
import operator as op | |
env = Env() | |
env.update({ | |
'+': op.add, | |
'-': op.sub, | |
'*': op.mul, | |
'/': op.truediv, | |
'>': op.gt, | |
'<':op.lt, | |
'>=': op.ge, | |
'<=': op.le, | |
'=': op.eq, | |
}) | |
return env | |
global_env = starndard_env() | |
global_env | |
def eval(x, env=global_env): | |
if isinstance(x, Symbol): return env.find(x)[x] | |
elif not isinstance(x, List): return x | |
else: | |
proc = eval(x[0], env) | |
args = [eval(arg, env) for arg in x[1:]] | |
return proc(*args) | |
def repl(prompt="(scheme)> "): | |
while True: | |
val = eval(parse(input(prompt))) | |
if val is not None: | |
print(val) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment