Skip to content

Commit

Permalink
adjust the project structure
Browse files Browse the repository at this point in the history
  • Loading branch information
mapan1984 committed Aug 7, 2017
1 parent 3b266d2 commit bad49eb
Show file tree
Hide file tree
Showing 10 changed files with 55 additions and 30 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
.vscode
__pycache__
myvenv
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
## Scheme 解释器

一个用Python完成的Scheme解释器。

### 使用

打开交互式解释器:

$ python run.py

或运行Scheme文件:

$ python run.py test.scm

### 代码功能

`scm`目录下为SCIP中解释器的实例程序。

`scmpy`为用Python完成的Scheme解释器,`run.py`为程序的入口。

27 changes: 3 additions & 24 deletions py/run.py → run.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,7 @@
import os
import sys

from data import *
from parse import InPort, parse
from evaluater import evaluate

def to_string(x):
"""Convert a Python object back into a Lisp-readable string."""
if x is True:
return "#t"
elif x is False:
return "#f"
elif isinstance(x, Symbol):
return x
elif isinstance(x, Strings):
return '"%s"' % x
elif isinstance(x, List):
return '('+' '.join(map(to_string, x))+')'
elif isinstance(x, complex):
return str(x).replace('j', 'i')
else:
return str(x)
from scmpy import InPort, parse, represent, evaluate

def repl(prompt=None, inport=InPort(sys.stdin), out=sys.stdout):
"""A prompt-read-eval-print loop."""
Expand All @@ -36,11 +17,9 @@ def repl(prompt=None, inport=InPort(sys.stdin), out=sys.stdout):
#sys.stderr.write(prompt)
print(prompt, end='', flush=True)
exp = parse(inport)
if exp is eof_object:
return
val = evaluate(exp)
if val is not None and out:
print(to_string(val), file=out)
print(represent(val), file=out)
except Exception as e:
print('%s: %s' % (type(e).__name__, e))

Expand All @@ -50,7 +29,7 @@ def load(filename):

def interpreter(prompt='Lispy> '):
"""Interactive interpreted lisp program."""
sys.stderr.write("Lispy version 2.0\n")
sys.stderr.write("Scmpy version 2.0\n")
repl(prompt=prompt)

def interpret(filename):
Expand Down
4 changes: 4 additions & 0 deletions scmpy/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from scmpy.parse import InPort, represent, parse
from scmpy.evaluater import evaluate

__all__ = ['InPort', 'represent', 'parse', 'evaluate']
2 changes: 1 addition & 1 deletion py/data.py → scmpy/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def Sym(s, symbol_table={}):
quasiquote_, unquote_, unquotesplicing_ = \
map(Sym, "quasiquote unquote unquote-splicing".split())

class Number():
class number():
def __init__(self, value):
if '.' in value:
self.value = float(value)
Expand Down
File renamed without changes.
4 changes: 2 additions & 2 deletions py/evaluater.py → scmpy/evaluater.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
Evaluate the expression.
"""

from data import *
from environment import Env, global_env
from scmpy.data import *
from scmpy.environment import Env, global_env

def cond_to_if(expr):
""""Convert the cond structure to an if construct."""
Expand Down
27 changes: 24 additions & 3 deletions py/parse.py → scmpy/parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
"""

import re
import io

from data import *
from scmpy.data import *

class InPort(object):
"""An input port. Retains a line of chars.
Expand All @@ -28,7 +29,10 @@ class InPort(object):
''', re.VERBOSE)

def __init__(self, file):
self.file = file
if isinstance(file, str):
self.file = io.StringIO(file)
else:
self.file = file
self.line = ''

def next_token(self):
Expand Down Expand Up @@ -70,6 +74,23 @@ def atom(token):

quotes = {"'":quote_, "`":quasiquote_, ",":unquote_, ",@":unquotesplicing_}

def represent(x):
"""Convert a Python object back into a Lisp-readable string."""
if x is True:
return "#t"
elif x is False:
return "#f"
elif isinstance(x, Symbol):
return x
elif isinstance(x, Strings):
return '"%s"' % x
elif isinstance(x, List):
return '('+' '.join(map(represent, x))+')'
elif isinstance(x, complex):
return str(x).replace('j', 'i')
else:
return str(x)

def parse(inport):
"""Read a Scheme expression from an input port and parse it."""
def read_ahead(token):
Expand All @@ -92,4 +113,4 @@ def read_ahead(token):
return atom(token)
# body of read
token1 = inport.next_token()
return eof_object if token1 is eof_object else read_ahead(token1)
return read_ahead(token1)
File renamed without changes.
File renamed without changes.

0 comments on commit bad49eb

Please sign in to comment.