Merge pull request #106 from fluentpython/main

lispy.py now runs in Python 3; dropped Python 2 support
This commit is contained in:
Peter Norvig
2021-06-29 09:12:49 -07:00
committed by GitHub

View File

@@ -4,9 +4,7 @@
################ Symbol, Procedure, classes
from __future__ import division
from __future__ import print_function
import re, sys, StringIO
import re, sys, io
class Symbol(str): pass
@@ -21,7 +19,7 @@ _quote, _if, _set, _define, _lambda, _begin, _definemacro, = map(Sym,
_quasiquote, _unquote, _unquotesplicing = map(Sym,
"quasiquote unquote unquote-splicing".split())
class Procedure(object):
class Procedure:
"A user-defined Scheme procedure."
def __init__(self, parms, exp, env):
self.parms, self.exp, self.env = parms, exp, env
@@ -33,12 +31,12 @@ class Procedure(object):
def parse(inport):
"Parse a program: read and expand/error-check it."
# Backwards compatibility: given a str, convert it to an InPort
if isinstance(inport, str): inport = InPort(StringIO.StringIO(inport))
if isinstance(inport, str): inport = InPort(io.StringIO(inport))
return expand(read(inport), toplevel=True)
eof_object = Symbol('#<eof-object>') # Note: uninterned; can't be read
class InPort(object):
class InPort:
"An input port. Retains a line of chars."
tokenizer = r"""\s*(,@|[('`,)]|"(?:[\\].|[^\\"])*"|;.*|[^\s('"`,;)]*)(.*)"""
def __init__(self, file):
@@ -83,7 +81,7 @@ def atom(token):
'Numbers become numbers; #t and #f are booleans; "..." string; otherwise Symbol.'
if token == '#t': return True
elif token == '#f': return False
elif token[0] == '"': return token[1:-1].decode('string_escape')
elif token[0] == '"': return token[1:-1]
try: return int(token)
except ValueError:
try: return float(token)
@@ -97,7 +95,7 @@ def to_string(x):
if x is True: return "#t"
elif x is False: return "#f"
elif isa(x, Symbol): return x
elif isa(x, str): return '"%s"' % x.encode('string_escape').replace('"',r'\"')
elif isa(x, str): return repr(x)
elif isa(x, list): return '('+' '.join(map(to_string, x))+')'
elif isa(x, complex): return str(x).replace('j', 'i')
else: return str(x)
@@ -158,7 +156,7 @@ def add_globals(self):
self.update(vars(math))
self.update(vars(cmath))
self.update({
'+':op.add, '-':op.sub, '*':op.mul, '/':op.div, 'not':op.not_,
'+':op.add, '-':op.sub, '*':op.mul, '/':op.truediv, 'not':op.not_,
'>':op.gt, '<':op.lt, '>=':op.ge, '<=':op.le, '=':op.eq,
'equal?':op.eq, 'eq?':op.is_, 'length':len, 'cons':cons,
'car':lambda x:x[0], 'cdr':lambda x:x[1:], 'append':op.add,